1. 所有对象都会有一个wait set,用于存放调用了该对象wait方法之后进入block状态的线程;
2. 线程被notify之后,不一定会立即执行;
3. 线程从wait set中唤醒的顺序不一定是FIFO;4. 线程被唤醒后,必须重新获取锁。
public class WaitSet {
    private final static Object lock = new Object();

    /**
     * 1. 所有对象都会有一个wait set,用于存放调用了该对象wait方法之后进入block状态的线程
     * 2. 线程被notify之后,不一定会立即执行
     * 3. 线程从wait set中唤醒的顺序不一定是FIFO
     * @param args
     * @throws InterruptedException
     */
    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 {
                            System.out.println(Thread.currentThread().getName() + " will come to wait");
                            lock.wait();
                            System.out.println(Thread.currentThread().getName() + " will leave to wait");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
        });
        // 让主线程暂停3秒,让所有的线程进入等待状态,再逐个进行唤醒
        TimeUnit.SECONDS.sleep(3);

        // 逐个唤醒线程
        IntStream.rangeClosed(1, 10).forEach(i->{
            synchronized (lock){
                lock.notify();
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

输出结果:

二、线程notify之后的操作

wait执行完,被其他线程唤醒的时候,需要再次去抢锁,且在其wait的时候会记录此时的地址,下次被唤醒抢到锁资源的时候就执行从记录的地址出向下执行。

测试代码如下:

public class WaitSet {
    private final static Object lock = new Object();

    private static void work(){
        synchronized (lock){
            System.out.println("begin...");
            try {
                System.out.println("thread is coming...");
                lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("thread will leave...");
        }
    }

    public static void main(String[] args) throws InterruptedException {

        new Thread(()->{
            work();
        }).start();

        TimeUnit.SECONDS.sleep(2);

        synchronized (lock){
            lock.notify();
        }
    }
}

输出结果:

ni

多线程的休息室WaitSet详细介绍的更多相关文章

  1. 城市经纬度 json 理解SignalR Main(string[] args)之args传递的几种方式 串口编程之端口 多线程详细介绍 递归一个List<T>,可自己根据需要改造为通用型。 Sql 优化解决方案

    城市经纬度 json https://www.cnblogs.com/innershare/p/10723968.html 理解SignalR ASP .NET SignalR 是一个ASP .NET ...

  2. JAVA多线程之间共享数据BlockingQueue介绍

    在JAVA的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利. ...

  3. Java 集合系列11之 Hashtable详细介绍(源码解析)和使用示例

    概要 前一章,我们学习了HashMap.这一章,我们对Hashtable进行学习.我们先对Hashtable有个整体认识,然后再学习它的源码,最后再通过实例来学会使用Hashtable.第1部分 Ha ...

  4. Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  5. kvm详细介绍

    KVM详解,太详细太深入了,经典 2016-07-18 19:56:38 分类: 虚拟化 原文地址:KVM详解,太详细太深入了,经典 作者:zzjlzx KVM 介绍(1):简介及安装 http:// ...

  6. 【转】Java 集合系列11之 Hashtable详细介绍(源码解析)和使用示例

    概要 前一章,我们学习了HashMap.这一章,我们对Hashtable进行学习.我们先对Hashtable有个整体认识,然后再学习它的源码,最后再通过实例来学会使用Hashtable.第1部分 Ha ...

  7. Java多线程学习(吐血超详细总结)

    Java多线程学习(吐血超详细总结) 林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 写在前面的话:此文只能说是java多线程的一个入门,其实 ...

  8. swoole运行模式加速laravel应用的详细介绍

    本篇文章给大家带来的内容是关于swoole运行模式加速laravel应用的详细介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 一.Swoole Swoole号称重新定义了PHP, ...

  9. 详细介绍如何自研一款"博客搬家"功能

    前言 现在的技术博客(社区)越来越多,比如:imooc.spring4All.csdn.cnblogs或者iteye等,有很多朋友可能在这些网站上都发表过博文,当有一天我们想自己搞一个博客网站时就会发 ...

随机推荐

  1. SQL优化 MySQL版 - 避免索引失效原则(一)

    避免索引失效原则(一) 精力有限,剩余的失效原则将会在 <避免索引失效原则(二)>中连载出来,请谅解 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 避免索引失效的一些原 ...

  2. kubernetes系列09—Ingress控制器详解

    本文收录在容器技术学习系列文章总目录 1.认识Ingress 1.1 什么是Ingress? 通常情况下,service和pod仅可在集群内部网络中通过IP地址访问.所有到达边界路由器的流量或被丢弃或 ...

  3. java 并发多线程 锁的分类概念介绍 多线程下篇(二)

    接下来对锁的概念再次进行深入的介绍 之前反复的提到锁,通常的理解就是,锁---互斥---同步---阻塞 其实这是常用的独占锁(排它锁)的概念,也是一种简单粗暴的解决方案 抗战电影中,经常出现为了阻止日 ...

  4. Java基础之 反射是什么?

    什么是反射,反射能干嘛? 反射是:指程序可以访问.检测和修改它本身状态或行为的一种能力 反射是一种能力,所以给的定义就是说明了它能干嘛. 我们平时用反射主要做: 获取类型的相关信息 动态调用方法 动态 ...

  5. 关于computed使用时报no-side-effects-in-computed-properties错误

    不要在计算属性内直接修改data里面的数据,eslint会报 no-side-effects-in-computed-properties 错误,如果非要改可以写在一个函数里,然后在计算属性里调用该函 ...

  6. PDF转图片工具

    点击下载( 提取码:1ll1 ) 软件功能基于mupdf,UI使用wxpython开发 功能: 支持pdf转图片,图片格式png 支持批量转换 使用: 第一步,点击按钮添加文档到列表,或直接将待转换文 ...

  7. C#自定义控件添加到工具箱

    1.在需要使用这个自定义控件的项目中,在引用中,右键,添加引用,浏览,找到dll(如:ComButton.dll),进行添加,这时候,控件应该是能够自动添加到工具箱的. 2.在Visual Studi ...

  8. 使用Linq的过程中碰到的问题

    1. 在使用linq过程DefaultIfEmpty的过程中如果 O.RS 这个支段的值是null,在取这个数据 就会报错 ,正确的写法 2. 在使用Linq 用where条件判断要好分辨大小写 3. ...

  9. WebStrom中实现Vue项目的快速启动

    工具:WebStrom+vue 前提:你已经安装了node.js,vuejs,会创建vue项目等一系列的操作 发生场景:希望在WebStrom中能够快速启动vue的项目,省去npm install,  ...

  10. LeetCode算法题-Longest Word in Dictionary(Java实现)

    这是悦乐书的第303次更新,第322篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第171题(顺位题号是720).给出表示英语词典的字符串单词数组,找到单词中长度最长的单 ...