【问题标题】:Notification in thread线程中的通知
【发布时间】:2013-11-30 18:31:33
【问题描述】:

一旦调用 notify() 方法,线程会立即放弃监视器,就像在 wait() 中发生的那样。或者调用notify()时,是否会在方法执行完成后释放monitor。

调用 notify() 时线程将进入哪个状态。等待还是阻塞状态?

【问题讨论】:

    标签: java multithreading notifications


    【解决方案1】:

    只要在对象上同步,线程就持有对象的监视器。被通知的线程将移动到BLOCKED 状态,并且一旦拥有线程释放它通过离开之前持有监视器的同步块/方法来获取监视器。

    例如,如果线程 A 阻塞了对 lock.wait() 的调用,而线程 B 调用了 lock.notify(),则线程 A 将离开 WAITING 状态并进入 BLOCKING 状态**,但线程 A 不会继续执行(即进入RUNNABLE状态)直到线程B离开synchronizedlock

    ** 假设没有其他线程在等待lock,因为不能保证通知线程的顺序,这就是为什么您应该使用notifyAll() 作为规则(除非您知道你正在做什么并且有充分的理由不这样做)。

    使用代码:

    public class ThreadStateTest {
    
        private static final Object lock = new Object();
    
        public static void main(String[] args) {
            synchronized (lock) {
                new Thread(new RunnableTest()).start();
                try {
                    Thread.sleep(1000);
                    System.out.println("this will print first");
                    lock.wait();
                    System.out.println("this will print third");
                } catch (InterruptedException ex) {
                }
            }
        }
    
        private static class RunnableTest implements Runnable {
            @Override
            public void run() {
                try {
                    synchronized (lock) {
                        lock.notifyAll();
                        Thread.sleep(1000);
                        System.out.println("this will print second");
                    }
                    Thread.sleep(1000);
                    System.out.println("this will print fourth");
                } catch (InterruptedException ex) {
                }
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      notify() 的情况下,拥有监视器的线程将继续持有监视器。

      notify()/notifyAll() 只是通知等待线程他们可以再次选择锁。一旦线程获得监视器,它将退出wait() 方法并继续。

      总结一下:一旦锁自然释放(同步块/方法之外),涉及notify()/notifyAll() 的线程将保持RUNNING 状态。

      通知的目的只是授权等待线程将来有机会在此可用时立即获得锁。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-05
        相关资源
        最近更新 更多