• 多线程的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();
            }

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

  • 相关阅读:
    HDU 1505 & POJ 1964 City Game (递推+扫描法)
    web页面内容优化管理与性能技巧
    POJ2406简单KMP
    poj2418map或者字典树
    poj2418map或者字典树
    POJ2296二分2sat
    POJ2296二分2sat
    poj2186强联通(牛仰慕)
    poj2186强联通(牛仰慕)
    poj2175费用流消圈算法
  • 原文地址:https://www.cnblogs.com/zheaven/p/12097970.html
Copyright © 2020-2023  润新知