zoukankan      html  css  js  c++  java
  • 多线程的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();
            }

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

  • 相关阅读:
    下载视频
    009 逻辑 + MFC CString
    008 浅拷贝与深拷贝
    007 operator
    006 this指针原理
    005 逻辑 + STL list
    004 list::sort
    003 逻辑 + mfc CList
    001 C++历史和思想
    并查集模板
  • 原文地址:https://www.cnblogs.com/zheaven/p/12097970.html
Copyright © 2011-2022 走看看