多线程的waitset详细介绍

代码演示

package com.dwz.concurrency2.chapter2;

import java.util.stream.IntStream;
/**
 * 1.所有的对象都会有一个wait set,用来存放调用了该对象wait方法之后进入block状态的线程
 * 2.线程被notify之后,不一定立即得到执行
 * 3.线程从wait set中被唤醒的顺序不一定是FIFO
 * 4.线程被唤醒后,必须重新去获取锁,会记录之前wait的位置,在wait的位置继续往下执行
 */
public class WaitSet {
    private static final Object LOCK = new Object();
    
    private static void work() {
        synchronized (LOCK) {
            System.out.println("begin...");
            
            try {
                System.out.println("Thread will come in.");
                LOCK.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Thread will out.");
        }
    }
}

测试一:验证线程从wait set中被唤醒的顺序不一定是FIFO

    IntStream.rangeClosed(1, 10).forEach(i-> 
            new Thread(String.valueOf(i)) {
                @Override
                public void run() {
                    synchronized (LOCK) {
                        try {
                            System.out.println(Thread.currentThread().getName() + " will come to wait set.");
                            LOCK.wait();
                            System.err.println(Thread.currentThread().getName() + " will leave to wait set.");
                        } 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();
                    }
                }
            }
        );

测试二:验证线程被唤醒后,必须重新去获取锁,会记录之前wait的位置,在wait的位置继续往下执行

     new Thread() {
            @Override
            public void run() {
                work();
            }
        }.start();
        
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        synchronized (LOCK) {
            LOCK.notifyAll();
        }

注意:线程不能进行自我唤醒,必须由其它线程唤醒

原文地址:https://www.cnblogs.com/zheaven/p/12097970.html