2.2-wait set(线程休息室)

原文链接:https://www.xttblog.com/?p=3294

自己根据大神博客画了一张图,望指正~~~

 

wait()方法

wait() 使当前线程处于等待状态,直到另外的线程调用 notify 或 notifyAll 将它唤醒。但是在等待唤醒的期间,它处在等待唤醒的池子中,也就是我们所说的等待池中。当调用 wait() 方法后,会释放锁,进入等待池。当调用 notify() 或 notifyAll() 后唤醒该对象监听的其中一个或所有线程(规则取决于JVM厂商,FILO,FIFO,随机…)。

等待池

假设线程 xttblog 调用了某个对象的 wait() 方法,则 xttblog 线程就会释放该对象的锁(因为 wait() 方法必须出现在 synchronized 中,所以在执行 wait() 方法之前 xttblog 线程就已经拥有了该对象的锁),同时线程 xttblog 进入到了该对象的等待池中。如果有其它线程调用了相同对象的 notifyAll() 方法,那么处于该对象的等待池中的线程就会全部进入该对象的锁池中,从新争夺锁的拥有权。如果另外的一个线程调用了相同对象的 notify() 方法,那么仅仅有一个处于该对象的等待池中的线程(随机)会进入该对象的锁池。

wait() 对应等待池,synchronized 对应锁池。

加了 synchronized 关键字的地方就会有相应的获取锁的步骤。未竞争到锁的线程会加入到锁池。

锁池

假设线程 xttblog 已经拥有了某个对象(注意:不是类)的锁,而其它的线程想要调用该对象的 synchronized 方法(或者 synchronized 块),其他未获得锁的线程在进入对象的 synchronized 方法之前都需要先获得该对象的锁的拥有权,但是该对象的锁目前正被 xttblog 线程拥有,所以这些线程就进入了该对象的锁池中。

等待池和锁池中的资源只要重新获得了对象的拥有权,那么就会被对应的池剔除。

示例代码

public class WaitSetTest {

    private static final Object LOCK = new Object();

    public static void main(String[] args) throws InterruptedException {
        IntStream.rangeClosed(1, 10).forEach(i ->
            new Thread(String.valueOf(i)) {
                @Override
                public void run() {
                    synchronized (LOCK) {
                        try {
                            Optional.of(Thread.currentThread().getName() + " will come to wait set.").ifPresent(System.out::println);
                            LOCK.wait();
                            Optional.of(Thread.currentThread().getName() + " will leave to wait set.").ifPresent(System.out::println);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start()
        );

        Thread.sleep(3000);

        IntStream.rangeClosed(1, 10).forEach(i -> {
                synchronized (LOCK) {
                    LOCK.notify();
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        );
    }
}
posted @ 2019-03-08 09:28  村里一枝梅  阅读(503)  评论(0)    收藏  举报