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();
            }

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

  • 相关阅读:
    iOS -- @try
    javaScript学习
    iOS -- js与原生交互
    iOS -- WKWebView
    iOS -- UIWindow的使用
    iOS -- app生命周期中代理方法的应用场景
    iOS -- keyChain
    UISegmentedControl
    明天你好
    编程:是一门艺术(转)
  • 原文地址:https://www.cnblogs.com/zheaven/p/12097970.html
Copyright © 2011-2022 走看看