【问题标题】:Working of Java wait methodJava等待方法的工作
【发布时间】:2018-03-29 06:54:13
【问题描述】:

我有以下代码:

   public class ThreadDemo {
    public static void main(String[] args) throws InterruptedException {
        ThreadImpl thr = new ThreadImpl();
        thr.start();
        Thread.sleep(1000);
        synchronized(thr){
            System.out.println( "MAIN "+thr.hashCode());
            System.out.println("Main -->got the lock");
            thr.wait();
            System.out.println("Main -->Done with waiting");
        }
    }
}

class ThreadImpl extends Thread{
    public synchronized void sayHello(){
        System.out.println("Ssay hello ");
    }
    @Override
    public void run() {
        synchronized(this){
            System.out.println( "METHOD "+this.hashCode());
            System.out.println("METHOD Got the lock ");
            System.out.println("METHOD Going for sleep ");
                for(int i =0;i< 100000;i++);
            try {
                Thread.sleep(2000);
                System.out.println("METHOD Woke up ");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("METHOD Done leaving the thread");
        }
    }
}

在 ThreadDemo 的 main 方法中,我正在创建一个线程对象 ThreadImpl 并启动它。接下来,主线程休眠 1000ms。 线程的 run 方法将在单独的线程中执行。作为其中的一部分,它循环 100000 次并休眠 2000ms。然后它退出该方法。 主线程唤醒并获取“thr”的锁,然后进入等待状态。由于另一个线程已经完成了它的执行,这个等待应该是永远的。但是,我看到以下结果:

方法 1729414014
方法 得到锁
方法 去睡觉
方法醒来
方法 完成离开线程
主 1729414014
主要 --> 获得了锁
Main -->等待完成

main方法在没有人通知的情况下如何继续执行?

【问题讨论】:

  • docs.oracle.com/javase/8/docs/api/java/lang/…。不要子类化线程。不要在线程上同步。不要等待线程。
  • 因为你有一个错字for(int i =0;i&lt; 100000;i++); - 删除分号
  • 同步 Runnable 的 run() 方法是完全没有意义的,除非你想共享 Runnable 本身
  • synchronizing on Thread许多奇怪的含义;尤其是Thread 在死亡时调用notifyAll - 这是join 框架的一部分。除非您真的知道自己在做什么不要Thread 实例上同步。更好的是,忘记 synchronized 关键字的存在。
  • @ScaryWombat 分号是故意的。我希望它在不做任何事情的情况下旋转 100000 次。这里的问题是谁在唤醒主线程(代码 sn-p 的第 9 行。)

标签: java multithreading synchronized synchronized-block


【解决方案1】:

这是虚假唤醒,见jls

线程可能由于任何一个原因而从等待集中移除 以下操作,并将在之后的某个时间恢复:

  • 正在对 m 执行通知操作,其中 t 被选择从等待集中移除。
  • 正在对 m 执行 notifyAll 操作。
  • 正在对 t 执行中断操作。
  • 如果这是一个定时等待,一个从 m 的等待集合中移除 t 的内部操作至少在毫秒毫秒后发生 nanosecs 自此等待开始以来经过的纳秒 行动。
  • 实施的内部操作。尽管不鼓励实现,但允许执行“虚假唤醒”,即从等待集中删除线程,从而在没有明确指示的情况下启用恢复

【讨论】:

  • 我不相信它是。正如我所说,这个唤醒是因为 Thread 在它死之前调用了 notifyAll
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多