java - Java中的多线程死锁

标签 java multithreading

拜托,有人能解释一下为什么这段代码是死锁吗?看起来它应该可以正常工作。请详细说明。谢谢。

public class H extends Thread {
    String info = "";
    public H (String info) {
        this.info = info;
    }

    public synchronized void run() {
        try {
            while (true) {
                System.out.println(info);
                notify();
                wait();
            }
        } catch (Exception e) {}

    }
    public static void main(String[] args) {
          new H("0").start();
          new H("1").start();
    }

最佳答案

每个线程都在 this 上同步(通过方法上的 synchronized 关键字),这对于两个线程对象中的每一个都是不同的。它们各自调用 notifywait 但它们不交互,因为 this 不同。因此,在第一次迭代中,它们都调用 wait 并永远阻塞,因为没有人可以唤醒它们。

以下是我为使代码按您的预期工作所做的一些更改。注意允许线程通信的共享静态字段:

public class Test extends Thread {
    String info = "";
    static final Object signal = new Object();
    static volatile String current = null;

    public Test (String info) {
        this.info = info;
    }

    public void run() {
        try {
            synchronized(signal) {
                while (true) {                                  
                    while(current.equals(info))
                        signal.wait();
                    System.out.println(info);
                    current = info;
                    signal.notify();
                }
            }
        } catch (Exception e) {}

    }

    public static void main(String[] args) {
        Test.current = "0";
        new Test("0").start();
        new Test("1").start();
    }
}

我想对您的原始代码做一些其他说明:

  • 您应该尝试实现 Runnable 而不是扩展 Thread。这样可以为您提供更大的灵 active 。
  • 不要吞下异常(exception)。

关于java - Java中的多线程死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13000679/

相关文章:

java - IllegalArgumentException Android 中的 SQLite 数据库绑定(bind)值索引 1 为 null

.net - 在EventWaitHandle发出信号后,对其进行处置是否安全?

Java 多线程访问静态变量

java - 为什么我在第 1 行收到语法错误?

java - Java 中使用 Google Guava 进行哈希处理时输出小写字符,而在线哈希站点则输出大写字符

java - Android - 检查 PDF 文件是否存在

java - Java 中的多线程 FTP 服务器

java - 如何在第 1 天后停止执行方法。时间?

c# - 在System.Threading中杀死旧线程并启动新线程

java - 在默认文本编辑器中打开任意文件的平台独立方式