高并发编程-Wait Set 多线程的“休息室”
生活随笔
收集整理的这篇文章主要介绍了
高并发编程-Wait Set 多线程的“休息室”
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
文章目录
- 概述
- 关于wait set
- 示例
- 思考
概述
官方指导: https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html
或者:
https://learning.oreilly.com/library/view/the-java-language/9780133260335/ch17lev1sec2.html
关于wait set
意思是说
示例
package com.artisan.test;import java.util.Optional; import java.util.stream.IntStream;public class WaitSet {// 显示定义一个锁private static final Object LOCK = new Object();public static void main(String[] args) throws InterruptedException {IntStream.rangeClosed(1, 10).forEach(i ->new Thread(String.valueOf("T_" + i)) {@Overridepublic void run() {synchronized (LOCK) {try {Optional.of(Thread.currentThread().getName() + " will come into wait set ..").ifPresent(System.out::println);LOCK.wait();Optional.of(Thread.currentThread().getName() + " will leave from wait set ...").ifPresent(System.out::println);} catch (InterruptedException e) {e.printStackTrace();}}}}.start());// 主线程休眠一秒,确保上面的10个线程都start ,不然的话 有可能 线程已经进入wait set ,10个线程还没都启动,就已经有线程离开 wait set了Thread.sleep(1_000);System.out.println("=====================10个线程启动完毕=======================");// 主线程中 每次notify 1个IntStream.rangeClosed(1, 10).forEach(i -> {synchronized (LOCK) {LOCK.notify();try {// 为了方便观察 休眠1秒Thread.sleep(1_000);} catch (InterruptedException e) {e.printStackTrace();}}});Thread.sleep(1_000);System.out.println("=====================OVER=======================");}}运行结果:
T_1 will come into wait set .. T_8 will come into wait set .. T_7 will come into wait set .. T_6 will come into wait set .. T_5 will come into wait set .. T_4 will come into wait set .. T_3 will come into wait set .. T_2 will come into wait set .. T_10 will come into wait set .. T_9 will come into wait set .. =====================10个线程启动完毕======================= T_1 will leave from wait set ... T_8 will leave from wait set ... T_7 will leave from wait set ... T_4 will leave from wait set ... T_5 will leave from wait set ... T_6 will leave from wait set ... T_10 will leave from wait set ... T_2 will leave from wait set ... T_3 will leave from wait set ... T_9 will leave from wait set ... =====================OVER=======================Process finished with exit code 0根据官网和我们的验证,总结一下
思考
有个方法如下:
private static void anotherThink() {synchronized (LOCK) {System.out.println("anotherThink begin to execute....");try {Optional.of(Thread.currentThread().getName() + " will come into wait set ...").ifPresent(System.out::println);LOCK.wait();} catch (InterruptedException e) {e.printStackTrace();}Optional.of(Thread.currentThread().getName() + " will leave from wait set ...").ifPresent(System.out::println);}}Q: 拿到锁后的第一件事情 是输出一行日志 anotherThink begin to execute.... 当线程1,抢到锁后 ,调用wait,放弃了执行权。 如果线程1被唤醒时,肯定要先获取到锁才能够执行,那我们刚才说的 抢到锁后打印日志会不会被执行呢?
我们来验证下
main方法中 测试代码如下
public static void main(String[] args) throws InterruptedException {/** new Thread("Test_Thread") {@Overridepublic void run() {anotherThink();}}.start() **/new Thread(() -> anotherThink() ,"Test Thread").start();Thread.sleep(1000);synchronized (LOCK) {LOCK.notify();}}运行日志
根据测试结论可知,是不会打印第一行的。 而是紧接着wait后面的代码执行,主要是源于JVM内部会记录上次代码的执行地址,进行地址恢复,继续执行。
A: 所以线程被唤醒后,必须重新获取锁,但是JVM内部会进行地址恢复,直接继续上次线程后续的逻辑
总结
以上是生活随笔为你收集整理的高并发编程-Wait Set 多线程的“休息室”的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 高并发编程-自定义简易的线程池(2),体
- 下一篇: 高并发编程-happens-before