【问题标题】:Does lock.notify() gets executed only at the end of the loop in a threadlock.notify() 是否仅在线程中的循环结束时执行
【发布时间】:2020-09-11 18:54:24
【问题描述】:
public class MyVisibility {

    private static int count = 0;
    private static Object lock = new Object();


    public static void main(String[] args) {
        new MyVisibility.thread1().start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            return;
        }
        new MyVisibility.thread2().start();
    }


    static class thread1 extends Thread {

        int i = 0;

        @Override
        public void run() {
            super.run();

            while (true) {

                synchronized (lock) {

                    count++;
                    System.out.println("Thread one count is  " + count);
                    try {
                        lock.wait();

                        System.out.println("i am notified");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                if (count > 5) {

                    return;
                }

            }


        }
    }


    static class thread2 extends Thread {

        int i = 10;

        @Override
        public void run() {
            super.run();

            while (true) {

                synchronized (lock) {


                    count++;
                    System.out.println("Thead 2 count  is " + count);

                    lock.notify();
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }


                if (count > 10) {
                    return;

                }

            }


        }
    }


}

在上面的代码中, 当前执行结果:我可以看到 lock.notify() 仅在 while 循环结束后才被调用。

我的假设是因为 lock.notify() 在 count 变量增加后立即被调用,并且它应该立即通知等待线程恢复其执行,而不是在第二个线程完成执行调用之后等待线程恢复,这是什么原因,有人可以纠正我的理解有什么问题吗。

谢谢。

【问题讨论】:

  • 请显示您的预期和实际输出。
  • 提示:在 synchronized 块或 synchronized 方法中调用 sleep(...) 实际上总是一个坏主意。
  • @SolomonSlow 是的,我知道,如果您在第一个线程上看到我没有使用睡眠,我正在尝试一些东西,并且在此处放置时没有删除第二个线程中的代码..跨度>

标签: java multithreading thread-safety wait notify


【解决方案1】:

您的推论 - “我可以看到 lock.notify() 仅在 while 循环结束后才被调用” 并不完全正确。尝试多次运行,或者在线程2的synchronized块之后放置断点,然后您将看到线程1 “我被通知”正在打印。

来自notify()的文档-

被唤醒的线程将无法继续,直到当前 线程放弃对该对象的锁定

在您的情况下,在线程 2 放弃锁定然后线程 1 获得锁定之前,线程 2 通过进入 synchronized 块再次获得锁定。

【讨论】:

  • 可能,调用 notify 确实会立即通知等待的线程,但我们不知道它什么时候会恢复执行。这取决于操作系统的调度程序来决定。例如,如果您的硬件在任何实例中仅支持一个活动线程,则 Thread1 将无法运行,直到 Thread2 完成其执行,这是否也可能是一个原因
  • 是的,有可能。
猜你喜欢
  • 1970-01-01
  • 2022-11-22
  • 1970-01-01
  • 1970-01-01
  • 2020-02-15
  • 2016-11-18
  • 1970-01-01
  • 2011-02-06
相关资源
最近更新 更多