高并发编程-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),体
- 下一篇: 高并发编程-通过volatile重新认识