【问题标题】:Java threading deadlock issue [duplicate]Java线程死锁问题[重复]
【发布时间】:2016-01-28 23:51:39
【问题描述】:

第一个代码:

公共类 H 扩展线程 {

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();
}

}

第二个代码:

公共类 H 扩展线程 {

String info = "";

static Object o = new Object();
public H (String info) {
    this.info    = info;
}
public synchronized void run() {
   try {

    while ( true )  {
        System.out.println(info);
        o.notify();
        o.wait();
    }
   } catch ( Exception e )  {}
}
public static void main (String args []) {
    new H("0").start();
    new H("1").start();
}

}

如果我同意第一个代码,它将进入死锁状态,因为同步运行方法永远不会释放锁。

但是为什么在第二个代码中,如果整个运行方法与没有对象 sill 同步,我试图等待并通知对象 o,它应该陷入死锁或连续运行代码(因为 while (true)),但是该代码以退出代码 0 存在。 谁可以帮我这个事。 提前谢谢!!!!

【问题讨论】:

  • 在第一个代码中,没有任何线程持有将唤醒等待线程的监视器锁。在第二个中,缺少的 printStackTrace() 隐藏了这个错误:java.lang.IllegalMonitorStateException 请参阅 API 文档了解 Object 类中的 wait 和 nofity 方法。

标签: java multithreading wait synchronized notify


【解决方案1】:

您拥有的第二个代码示例并没有按照您的想法执行。

你只是抓住Exception 并将其埋葬,没有任何信息。当o.notify() 被调用时,它会抛出一个IllegalMonitorStateException,因此会跳出while 循环并导致您的程序以返回码0 退出。

为了正确调用通知,当前执行的线程必须对你通知的对象有一个锁。

在示例 1 中,同步的 run() 方法对 this 进行了锁定,因此您可以执行 this.notify()

但是,在第二个示例中,当您通知对象o 时,它没有同步,从而导致IllegalMonitorStateException。

这是第二版代码的“固定”副本。这将在打印 0 和 1 之间无限循环,我认为这是您所期望的:

public class H extends Thread{
    String info = "";

    static Object o = new Object();
    public H (String info) {
        this.info    = info;
    }

    public synchronized void run() {
       try {

        while ( true )  {
            System.out.println(info);
            synchronized(o){
                o.notify();
                o.wait();
            }
        }
       } catch ( Exception e )  {
           throw new RuntimeException(e);
       }
    }
    public static void main (String args []) {
        new H("0").start();
        new H("1").start();
    }
}

【讨论】:

  • 没错,但它甚至没有抛出 IllegalMonitorStateException
  • “它”是什么意思?
猜你喜欢
  • 1970-01-01
  • 2011-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-20
相关资源
最近更新 更多