線程安全3--wait和notify

文章目錄

  • wait and notify(等待通知機制
  • notify
  • 補充

wait and notify(等待通知機制

引入wait notify就是為了能夠從應用層面上,干預到多個不同線程代碼的執行順序,這里說的干預,不是影響系統的線程調度策略(內核里調度線程,仍然是無序調度)
相當于是在應用程序代碼中,讓后執行的線程,主動放棄被調度的機會,就可以讓先執行的線程,先把對應代碼執行完了
舉例:
在ATM機上取錢
在這里插入圖片描述
ATM通過鎖來互斥
第一個人,先進去,發現ATM沒錢,然后出來了,但是和其他人來競爭這個ATM,參與到了鎖競爭中,此時完全有可能第一個人再次拿到這個鎖,如果反復如此,就會導致第一個人反復獲取到鎖,但又無法完成實質性的邏輯,導致“線程餓死”。
這種情況就是嚴重的bug,當第一個人發現自己要執行的邏輯,前提條件不具備,在這種情況下,應該主動放棄對鎖的競爭,一直到條件具備,此時再解除阻塞,參與鎖競爭,這個時候就要用到wait和notify
在這里插入圖片描述
join是等待另一個線程執行完,才繼續執行
wait則是等待另一個線程通過notify進行通知(不要求另一個線程必須執行完)
wait進入阻塞,只能說明自己釋放鎖了
其他線程是否拿到了鎖,另當別論

阻塞產生的原因有好幾種:
1.sleep TIMED_WAITING
2.join/wait WAITING
3.synchronized BLOCKED

Object object = new Object();object.wait();

隨便拿一個對象都能調用wait但是運行起來會報異常
在這里插入圖片描述
不合法監視狀態異常
原因:wait一旦調用就會釋放鎖,釋放鎖的前提是拿到鎖,所以,wait必須放到synchronized里面使用。
wait鎖對象必須和synchronized鎖對象一致

public class Test4 {public static void main(String[] args) {Object object = new Object();Thread t1 = new Thread(()->{synchronized (object){System.out.println("wait前");try {object.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("wait后");}});t1.start();}
}

輸出結果:

wait前

代碼一直沒有結束

在Java監視和管理控制臺上:
在這里插入圖片描述

notify

鎖被wait就需要來喚醒鎖,notify就是來喚醒鎖的
notify可以不放在synchronized里面,但是Java規定notify必須放在synchronized里面

public class Test4 {public static void main(String[] args) throws InterruptedException {Object object = new Object();Thread t1 = new Thread(()->{synchronized (object){System.out.println("wait前");try {object.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("wait后");}});Thread t2 = new Thread(()->{try {Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized(object){System.out.println("notify前");object.notify();System.out.println("notify后");}});t1.start();t2.start();}
}

運行結果:

wait前
notify前
notify后
wait后

線程2使用sleep的原因
因為線程調度是隨機的,不確定線程1還是線程2先運行,如果線程2先運行就達不到我們預期的結果,所以sleep線程2,讓線程1先運行,先執行wait,再執行notify。

上述代碼運行執行過程:
1.t1先執行起來后,就會立即拿到鎖,并打印wait前,然后進入wait方法(釋放鎖+阻塞等待)
2.t2執行起來,先進行sleep五秒(為了讓t1先拿到鎖)
3.t2sleep結束后,由于t1是wait狀態,鎖是釋放的,t2就能拿到鎖,接下來打印notify前,執行notify操作,喚醒t1
4.由于t2還沒有釋放鎖,t1想要獲取鎖,可能會出現阻塞,和t2鎖競爭導致
5.t2打印notify后,釋放鎖,t2執行完畢,t1獲取到鎖,打印wait后

補充

在這里插入圖片描述
在這里插入圖片描述

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

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

相關文章

uni-app應用設置 可以根據手機屏幕旋轉進行 (橫/豎) 屏切換

首先 我們打開項目的 manifest.json 在左側導航欄中找到 源碼視圖 然后找到 app-plus 配置 在下面加上 "orientation": [//豎屏正方向"portrait-primary",//豎屏反方向"portrait-secondary",//橫屏正方向"landscape-primary",//橫屏…

第57天:django學習(六)

模版之過濾器 語法: {{obj|filter__name:param}} 變量名字|過濾器名稱:變量 default 如果一個變量是false或者為空,使用給定的默認值。否則,使用變量的值。例如: {{ value|default:"nothing"}} length …

IDEA啟動應用時報錯:錯誤: 找不到或無法加載主類 @C:\Users\xxx\AppData\Local\Temp\idea_arg_filexxx

IDEA啟動應用時報錯,詳細錯誤消息如下: C:\devel\jdk1.8.0_201\bin\java.exe -agentlib:jdwptransportdt_socket,address127.0.0.1:65267,suspendy,servern -XX:TieredStopAtLevel1 -noverify -Dspring.output.ansi.enabledalways -Dcom.sun.management…

基于以太坊的智能合約開發Solidity(事件日志篇)

//聲明版本號(程序中的版本號要和編譯器版本號一致) pragma solidity ^0.5.17; //合約 contract EventTest {//狀態變量uint public Variable;//構造函數constructor() public{Variable 100;}event ValueChanged(uint newValue); //事件聲明event Log(…

ElasticSearch之cat plugins API

命令樣例如下: curl -X GET "https://localhost:9200/_cat/plugins?vtrue&pretty" --cacert $ES_HOME/config/certs/http_ca.crt -u "elastic:ohCxPHQBEs5*lo7F9"執行結果輸出如下: name component version…

class064 Dijkstra算法、分層圖最短路【算法】

class064 Dijkstra算法、分層圖最短路【算法】 算法講解064【必備】Dijkstra算法、分層圖最短路 code1 743. 網絡延遲時間 // Dijkstra算法模版(Leetcode) // 網絡延遲時間 // 有 n 個網絡節點,標記為 1 到 n // 給你一個列表 times&…

法律服務網站建設效果如何

律師事務所及法律知識咨詢機構等往往是眾多人群需求的服務,服務多樣化及內容多元化,市場中也有大量品牌,在實際消費服務中大多以本地事務所為主,而線上咨詢服務則一般沒有區域限制,同行增多及人們知識獲取渠道增加&…

C++-引用和指針區別

文章目錄 1.變量的組成2.指針2.1 定義2.2 使用指針操作變量2.3 為什么使用指針 3.引用3.1 定義3.2 引用注意事項 4.引用和指針的區別 1.變量的組成 變量的組成:變量地址,變量名,變量值 例: int i 12;2.指針 2.1 定義 指針用于存…

如何為游戲角色3D模型設置紋理貼圖

在線工具推薦: 3D數字孿生場景編輯器 - GLTF/GLB材質紋理編輯器 - 3D模型在線轉換 - Three.js AI自動紋理開發包 - YOLO 虛幻合成數據生成器 - 三維模型預覽圖生成器 - 3D模型語義搜索引擎 當談到游戲角色的3D模型風格時,有幾種不同的風格&#xf…

Mybatis中的查詢操作

單表查詢 單表查詢在《初始Mybatis》中已經介紹過&#xff0c;這里就不在介紹了。咱們這里只說單表查詢中的“like查詢”。like查詢單獨使用#{}報錯 <select id"selectByKeyword" resultType"com.example.demo.entity.Userinfo">select * from use…

計網Lesson8 - NAT技術與鏈路層概述

文章目錄 NAT 技術1. 因特網的接入方式2. 公網和私網3. NAT 技術 鏈路層1. 數據鏈路層概述2. 數據鏈路層的三個問題2.1 封裝成幀2.2 透明傳輸2.3 差錯檢測 NAT 技術 1. 因特網的接入方式 光貓將電信號轉換為數字信號發送給路由器 光纖入戶 光纖傳遞的就是數字信號&#xff0c…

python+pytest接口自動化(12)-自動化用例編寫思路 (使用pytest編寫一個測試腳本)

經過之前的學習鋪墊&#xff0c;我們嘗試著利用pytest框架編寫一條接口自動化測試用例&#xff0c;來厘清接口自動化用例編寫的思路。 我們在百度搜索天氣查詢&#xff0c;會出現如下圖所示結果&#xff1a; 接下來&#xff0c;我們以該天氣查詢接口為例&#xff0c;編寫接口測…

錯題總結(三)

1.寫代碼將三個整數數按從大到小輸出。 例如&#xff1a; 輸入&#xff1a;2 3 1 輸出&#xff1a;3 2 1 int main() {int a 0;int b 0;int c 0;int tep 0;scanf("%d%d%d", &a, &b, &c);if (a < b){tep a;a b;b tep;}if (b < c){tep b…

每日一練2023.12.9—— 矩陣A乘以B【PTA】

題目鏈接&#xff1a;L1-048 矩陣A乘以B 題目要求&#xff1a; 給定兩個矩陣A和B&#xff0c;要求你計算它們的乘積矩陣AB。需要注意的是&#xff0c;只有規模匹配的矩陣才可以相乘。即若A有Ra?行、Ca?列&#xff0c;B有Rb?行、Cb?列&#xff0c;則只有Ca?與Rb?相等時&a…

Linux Shell 基礎命令

Linux 是一個開源的操作系統&#xff0c;其命令行界面是它的重要組成部分。在這個界面下&#xff0c;Shell 是一個能夠與操作系統進行交互的工具。Shell 是一種程序&#xff0c;它能夠接收用戶輸入的命令&#xff0c;并將這些命令發送到操作系統中進行處理。 在 Linux 中&…

Docker實戰筆記 三 Docker私有庫

1.拉取私有庫image rootcenots-7.5:/root#docker pull registry Using default tag: latest latest: Pulling from library/registry c926b61bad3b: Pull complete 5501dced60f8: Pull complete e875fe5e6b9c: Pull complete 21f4bf2f86f9: Pull complete 98513cca25bb: P…

VINS-MONO代碼解讀5----vins_estimator(marginalization部分)

文章目錄 0. 前言1.1 Marginalization Pipiline 1. marg factor構建1.1 變量及維度理解1.2 IMUFactor1.3 ProjectionTdFactor(ProjectionFactor)1.4 MarginalizationFactor( e p e_p ep?推導更新&#xff0c;FEJ解決的問題)1.4.1 先驗殘差的更新1.4.2 先驗Jacobian的更新 2. R…

windows install git

refer: https://developers.weixin.qq.com/miniprogram/dev/devtools/wechatvcs.html https://blog.csdn.net/weixin_40228200/article/details/128451324 在使用小程序的時候&#xff0c;需要初始化項目&#xff0c;需要注冊Git賬號 1.在本地確認cmd沒有安裝Git,進入Git官網…

docker:安裝mysql以及最佳實踐

文章目錄 1、拉取鏡像2、運行容器3、進入容器方式一方式二方式三容器進入后連接mysql和在宿主機連接mysql的區別 持久化數據持久化數據最佳實踐 1、拉取鏡像 docker pull mysql2、運行容器 docker run -d -p 3307:3306 --name mysql-container -e MYSQL_ROOT_PASSWORD123456 …

Botton進一步了解(點擊事件)

點擊事件和長按事件 監聽器&#xff1a;專門監聽控件的動作行為。只有控件發生了指定的動作&#xff0c;監聽器才會觸發開關區執行對應的代碼邏輯。按鈕控件有兩種常用的監聽器&#xff1a; 點擊監聽器&#xff1a;通過setOnClickListener方法設置。按鈕被按住少于500ms時會觸…