等待和通知

引入

由于線程是搶占式執行的,因此線程之間的執行的先后順序難以預知

但是實際開發中我們希望合理協調多個線程之間執行的先后順序.

這里的干預線程先后順序,并不是影響系統的調度策略(內核里調度線程,仍然是無序調度).

就是相當于在應用程序代碼中,讓后執行的線程主動放棄被調度的機會.就可以讓執行線程,先把對應的代碼執行完了.

完成這個協調工作,主要涉及到三個方法

wait()/wait(long timeout):讓當前線程進入準備狀態.

notify()/notifyAll():喚醒在當前對象上等待的線程.

注意:wait,notify,notifyAll都是Object類的方法.

wait()方法

一個線程重復拿到鎖,別的線程無法拿到鎖,這個情況稱為"線程餓死/饑餓".屬于概率性事件.雖然不像死鎖那樣嚴重.這種情況確實是bug.沒那么嚴重,但也極大地影響了程序的運行.

處理:使該線程主動放棄對鎖的爭奪/放棄去cpu調度執行(進入阻塞,也就是wait).一直到這個條件具備,再解除阻塞,參與鎖競爭.

wait做的事情:

1.使當前執行代碼的線程進行等待.(把線程放到等待隊列中).

2.釋放當前的鎖.

3.滿足一定條件時被喚醒,重新嘗試獲取這個鎖.

其中,1,2條可以讓其他線程有機會拿到鎖了.第三條指當其它線程調用notify的時候,wait解除阻塞.

wait結束等待的條件:

1.其它線程調用該對象的notify方法.

2.wait等待時間超時(wait方法提供一個帶有timeout參數的版本,來指定等待時間)->這是為了防止死等,具有魯棒性

3.其它線程調度該等待線程的interrupted方法,導致wait拋出InterruptException異常.

觀察wait()方法的使用:

public static void main(String[] args) throws InterruptedException {Object locker = new Object();synchronized (object) {System.out.println("等待中");object.wait();System.out.println("等待結束");}
}

這樣執行到object.wait()之后就會一直等待下去,那么程序肯定不能這樣一直等待下去了.這個時候就需要使用到了另外一個方法以喚醒,也就是notify().

notify方法

notify方法是喚醒等待的線程.

?1.方法notify()也要在同步方法或同步塊中調用,該方法是用來通知那些可能等待該對象的對象鎖的其它線程,對其發出通知notify,并使它們重新獲取該對象的對象鎖.

2.如果有多個線程等待,則有線程調度器隨機挑選出一個呈wait狀態的線程.(前提是操作的是同一個鎖).并沒有"先來后到"

3.在notify()方法后,當前線程不會馬上釋放該對象鎖,要等到執行notify()方法的線程將程序執行完,也就是退出同步代碼塊之后才會釋放對象鎖.

代碼示例:

public class ThreadTest5 {public static Object locker = new Object();public static void main(String[] args) {Thread t1 = new Thread(() -> {synchronized (locker) {System.out.println("t1 wait 之前");try {//t1執行起來之后,執行到這,就會先立即釋放鎖,進入wait方法(釋放鎖+阻塞等待)locker.wait();System.out.println("t1 wait 之后");} catch (InterruptedException e) {e.printStackTrace();}}});Thread t2 = new Thread(() -> {try {//t2執行起來之后,先進行sleep(3000)(這個sleep操作就可以讓t1先拿到鎖)//如果先notify雖然不會有副作用(不會出現異常之類的),但是wait就無法被喚醒,邏輯上有問題Thread.sleep(3000);//t2sleep結束之后,由于t1是wait狀態,t2就能拿到鎖//接下來打印t2notify之前,執行notify操作,這個操作就能喚醒t1(此時t1就從WAITING狀態恢復過來了)synchronized (locker) {System.out.println("t2 notify 之前");locker.notify();//但是由于t2此時還沒有釋放鎖,WAITING恢復之后,嘗試獲取鎖,就可能出現一個小小的阻塞,這個阻塞是由鎖競爭引起的//t1目前處于BLOCKED狀態,但是時間比較短,肉眼看不見System.out.println("t2 notify 之后");}//t2釋放鎖之后,就可以繼續執行t1} catch (InterruptedException e) {e.printStackTrace();}});t1.start();t2.start();}
}

notifyAll()方法

notify方法只是喚醒某一個等待線程.使用notifyAll方法可以一次喚醒所有的等待線程.

但是注意,這些線程在wait返回時,要重新獲取鎖,就會因為鎖的競爭,使這些線程實際上是一個一個串行執行的(誰先誰后拿到鎖是不一定的).?

?理解notify和notifyAll

notify只喚醒等待隊列中的一個線程.其它線程還是乖乖等著

notifyAll一下全都喚醒,需要這些線程重新競爭鎖.

相比之下,還是更傾向于notify.因為notifyAll全部喚醒之后,不好控制

?wait和sleep的對比

其實理論上wait和sleep完全是沒有可比性的,因為一個是用于線程之間通信的,一個是讓線程阻塞一段時間,唯一的共同的就是都可以讓線程放棄執行一段時間.

1.wait可通過notify喚醒,sleep通過Interrupt喚醒

2.使用wait的最主要的目標,一是不知道奪少時間的前提下使用的.所謂的"超時間",就是"兜底"

使用sleep,一定是直到多少時間的前提下使用的,這個操作不因該作為正常業務邏輯(通過異常喚醒,說明程序應該是出現特殊情況了)

3.wait搭配synchronized使用,sleep不需要

4.wait是Object的方法,sleep是Thread的靜態方法

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/208054.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/208054.shtml
英文地址,請注明出處:http://en.pswp.cn/news/208054.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

3DCAT+上汽奧迪:打造新零售汽車配置器實時云渲染解決方案

在 5G、云計算等技術飛速發展的加持下,云渲染技術迎來了突飛猛進的發展。在這樣的背景下,3DCAT應運而生,成為了業內知名的實時云渲染服務商之一。 交互式3D實時云看車作為云渲染技術的一種使用場景,也逐步成為一種新的看車方式&a…

設備溫度和振動綜合監測:溫振一體式傳感器的優點和應用

隨著工業設備的復雜性和自動化程度的提高,對設備狀態監測的需求也日益增加。溫振一體式傳感器作為一種集振動和溫度監測于一體的傳感器,具備多項優勢,因此在工業設備狀態監測領域得到廣泛應用。 溫振一體式傳感器基于振動傳感器和溫度傳感器的…

1380 一筆畫問題

如果一個無向圖存在一筆畫&#xff0c;則一筆畫的路徑叫做歐拉路&#xff0c;如果最后又回到起點&#xff0c;那這個路徑叫做歐拉回路。 #include<bits/stdc.h> using namespace std; #define N 510 int g[N][N],d[N],c[N],n,m,reckon,oddity_point,lt; void dfs(int i)…

網絡運維與網絡安全 學習筆記2023.12.1

網絡運維與網絡安全 學習筆記 第三十二天 今日目標 ACL原理與類型、基本ACL配置、高級ACL配置 高級ACL之ICMP、高級ACL之telnet ACL原理與類型 項目背景 為了企業的業務安全&#xff0c;要求不同部門對服務器有不同的權限 PC1不能訪問Server PC2允許訪問Server 允許其他所…

java中用Thead創建線程和用Runnable創建線程的區別是什么?

在 Java 中&#xff0c;創建線程的兩種主要方式是通過繼承 Thread 類和通過實現 Runnable 接口。下面是它們之間的主要區別&#xff1a; 1. 繼承 Thread 類&#xff1a; class MyThread extends Thread {public void run() {// 線程執行的代碼} }// 創建并啟動線程 MyThread …

043:vue項目一直出現 sockjs-node/info?t=XX的解決辦法

第043個 查看專欄目錄: VUE ------ element UI 專欄目標 在vue和element UI聯合技術棧的操控下&#xff0c;本專欄提供行之有效的源代碼示例和信息點介紹&#xff0c;做到靈活運用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安裝、引用&#xff0c;模板使…

Linux文件系統與基礎IO

文章目錄 1 C文件接口1.1 fopen1.2 fwrite、fread、rewind、fclose 2 文件系統調用2.1 open2.1.1 參數2&#xff1a;flags2.1.2 參數3&#xff1a;mode2.1.3 返回值——file descriptor 2.2 write2.3 read2.4 close 3 文件的本質3.1 struct file3.2 一個進程如何與多個文件相關…

數據分析入門語言:選擇SQL還是Python?如何選擇你的第一門編程語言?

【關注微信公眾號&#xff1a;跟強哥學SQL&#xff0c;回復“筆試”免費領取大廠SQL筆試題。】 如今數據爆炸的時代&#xff0c;掌握一門數據分析的編程語言變得愈發重要。 而隨著SQL和Python在數據分析領域的持續火熱&#xff0c;許多初學者面臨著一個共同的問題&#xff1a;…

Python 日志指南

目錄 日志指南 日志基礎教程 什么時候使用日志 一個簡單的例子 記錄日志到文件 從多個模塊記錄日志 記錄變量數據 更改顯示消息的格式 在消息中顯示日期/時間 后續步驟 進階日志教程 記錄流程 記錄器 處理器 格式器 配置日志記錄 如果沒有提供配置會發生什么 …

QLoRA論文概述

QLORA: Efficient Finetuning of Quantized LLMs QLoRA論文概述前言&#xff08;省流版本&#xff09;摘要論文十問實驗實驗1數據集和模型實驗結論 實驗2數據集和模型實驗結論 局限性模型尺度數據集其他微調方法 QLoRA論文概述 前言&#xff08;省流版本&#xff09; 微調需要…

期末速成數據庫極簡版【查詢】(2)

目錄 select數據查詢----表 【1】篩選列 【2】where簡單查詢 【3】top-n/distinct/排序的查詢 【4】常用內置函數 常用日期函數 常用的字符串函數 【5】模糊查詢 【6】表數據操作——增/刪/改 插入 更新 刪除 【7】數據匯總 聚合 分類 ? &#x1f642;&#…

人大金倉(kingbase)數據庫常用sql命令

一. 字段 1. 添加 alter table book add column book_id varchar not null, book_title varchar(10) default ;2. 刪除 alter table book drop book_id, book_title;// 外鍵時 alter table book drop book_id, book_title cascade;3. 修改類型 alter table book alter colu…

分享十幾個適合新手練習的軟件測試項目

說實話&#xff0c;在找項目的過程中&#xff0c;我下載過&#xff08;甚至付費下載過&#xff09;N多個項目、聯系過很多項目的作者&#xff0c;但是絕大部分項目&#xff0c;在我看來&#xff0c;并不適合你拿來練習&#xff0c;它們或多或少都存在著“問題”&#xff0c;比如…

12v轉48v升壓電源芯片:參數、特點及應用領域

12v轉48v升壓電源芯片&#xff1a;參數、特點及應用領域 隨著電子設備的日益普及&#xff0c;電源芯片的需求也在不斷增長。今天我們將介紹一款具有廣泛應用前景的升壓電源芯片——12v轉48v升壓電源芯片。該芯片具有寬輸入電壓范圍、高效率、固定工作頻率等特點&#xff0c;適…

android 13.0 系統屬性控制音量鍵功能是否可用開關(屏蔽音量加減功能)

1.概述 在13.0的系統定制化開發中,要求屏蔽掉音量+ 音量-的功能,根據系統屬性來判斷是否響應音量加減的功能,在系統上層中是由PhoneWindowManage來管理音量鍵的功能, 所以就要看是PhoneWindowManage.java中怎么處理的音量鍵的功能 首選看的源碼關于音量鍵的處理 2.系統屬…

mp3的播放

1.這段vue代碼會播放聲音&#xff0c;但是會有audio標簽 <template><div><audio id"myAudio" controls><source src"./test.mp3" type"audio/mp3" />Your browser does not support the audio tag.</audio></…

ubuntu22.04安裝過程記錄

安裝雙系統ubuntu22.04 【雙系統】如何安裝ubuntu22.04系統_ubuntu安裝教程-CSDN博客 更換清華源 打開清華源官網&#xff0c;搜索對應系統版本的鏡像源碼 https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/ 原文件備份 sudo cp /etc/apt/sources.list /etc/apt/source…

庫卡LBR_iisy_3_R760協作機器人導入到coppeliasim

1.從庫卡官網xpert下載模型 一般載都是這個step文件格式&#xff0c;其他的好像不太好用。coppeliasim導入格式用的是stl,需要用freeCAD打開重新轉換一下。下載下來后&#xff0c;很多都是一個整體&#xff0c;在freeCAD導入中&#xff0c;導入選擇要不勾選合并。 下載完用CAD …

正則表達式詳細講解

目錄 一、正則表達式概念 二、八元素 1、普通字符&#xff1a; 2、元字符&#xff1a; 3、通配符 .&#xff1a; 4、字符類 []&#xff1a; 5、量詞&#xff1a; 6、錨點 ^ 和 $&#xff1a; 7、捕獲組 ()&#xff1a; 8、轉義字符 \&#xff1a; 三、日常使用的正則…

markdown記錄

文章目錄 基礎操作使用一級列表、二級列表 博文鏈接 基礎操作 使用一級列表、二級列表 博文鏈接 CSDN-Markdown語法集錦 CSDN-markdown語法之如何使用LaTeX語法編寫數學公式 CSDN Markdown簡明教程1-關于Markdown CSDN Markdown簡明教程2-基本使用 CSDN Markdown簡明教程3-表…