Java多線程4:synchronized鎖機制

臟讀

一個常見的概念。在多線程中,難免會出現在多個線程中對同一個對象的實例變量進行并發訪問的情況,如果不做正確的同步處理,那么產生的后果就是"臟讀",也就是取到的數據其實是被更改過的。

?

?

?

按照正常來看應該打印"a num = 100"和"b num = 200"才對,現在卻打印了"b num = 200"和"a num = 200",這就是線程安全問題。我們可以想一下是怎么會有線程安全的問題的:

1、mt0先運行,給num賦值100,然后打印出"a set over!",開始睡覺

2、mt0在睡覺的時候,mt1運行了,給num賦值200,然后打印出"b set over!",然后打印"b num = 200"

3、mt1睡完覺了,由于mt0的num和mt1的num是同一個num,所以mt1把num改為了200了,mt0也沒辦法,對于它來說,num只能是100,mt0繼續運行代碼,打印出"a num = 200"

分析了產生問題的原因,解決就很簡單了,給addNum(String userName)方法加同步即可:

?

打印結果的方式變了,打印的順序是交叉的,這又是為什么呢?

這里有一個重要的概念。關鍵字synchronized取得的鎖都是對象鎖,而不是把一段代碼或方法(函數)當作鎖,哪個線程先執行帶synchronized關鍵字的方法,哪個線程就持有該方法所屬對象的鎖,其他線程都只能呈等待狀態。但是這有個前提:既然鎖叫做對象鎖,那么勢必和對象相關,所以多個線程訪問的必須是同一個對象

如果多個線程訪問的是多個對象,那么Java虛擬機就會創建多個鎖,就像上面的例子一樣,創建了兩個ThreadDomain13對象,就產生了2個鎖。既然兩個線程持有的是不同的鎖,自然不會受到"等待釋放鎖"這一行為的制約,可以分別運行addNum(String userName)中的代碼。

?

?

synchronized方法與鎖對象

?

?

從結果看到,第一個線程調用了實體類的methodA()方法,第二個線程完全可以調用實體類的methodB()方法。但是我們把methodB()方法改為同步就不一樣了,就不列修改之后的代碼了,看一下運行結果:

?

?

從這個例子我們得出兩個重要結論:

1、A線程持有Object對象的Lock鎖,B線程可以以異步方式調用Object對象中的非synchronized類型的方法

2、A線程持有Object對象的Lock鎖,B線程如果在這時調用Object對象中的synchronized類型的方法則需要等待,也就是同步

?

synchronized鎖重入

關鍵字synchronized擁有鎖重入的功能。所謂鎖重入的意思就是:當一個線程得到一個對象鎖后,再次請求此對象鎖時時可以再次得到該對象的鎖。看一個例子:

看到可以直接調用ThreadDomain16中的打印語句,這證明了對象可以再次獲取自己的內部鎖。這種鎖重入的機制,也支持在父子類繼承的環境中

?

?

異常自動釋放鎖

最后一個知識點是異常。當一個線程執行的代碼出現異常時,其所持有的鎖會自動釋放。模擬的是把一個long型數作為除數,從MAX_VALUE開始遞減,直至減為0,從而產生ArithmeticException。看一下例子:

因為打印結果是靜態的,所以不是很明顯。在l--前一句加上Thread.sleep(1)結論會更明顯,第一句打出來之后,整個程序都停住了,直到Thread-0拋出異常后,Thread-1才可以運行,這也證明了我們的結論。

?

?

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

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

相關文章

mysql 日期時間類型 自動轉型 及 運算

日期時間類型自動轉型 -- now()、字符串、數字轉datetime類型 create table t(dt datetime);insert into t values(now());insert into t values(2007-9-3 12:10:10);insert into t values(2007/9/3 121010);insert into t values(2007#9#3 121010);insert into t values(20079…

.NET Community Toolkit 8.0.0 版本發布

.NET 社區工具包(.NET Community Toolkit )現已發布 8.0.0 版!.NET 社區工具包是一組適用于所有 .NET 開發人員,且與任何特定 UI 平臺無關的幫助程序和 API。該工具包由 Microsoft 維護和發布,是 .NET 基金會的一部分&…

SpringData JPA、Hibernate、Mybatis三者的區別

目錄 1.ORM 考慮 SpringData JPA Hibernate MyBatis 2.業務查詢的區別 Spring Data JPA Hibernate Mybatis 3.可拓展性 Spring Data JPA Hibernate Mybatis 4.對緩存 Spring Data JPA Hibernate Mybatis 5.難度性 Spring Data JPA Hibernate Mybatis 總述…

1、內存

程序為什么需要內存 程序運行的目的:程序運行是為了得到一定的結果,程序運行其實是在做一系列的數據計算,所以:程序代碼數據;程序運行的目的不外乎2個:過程、結果; 用函數來類比:…

Map 遍歷取值及jstl的取值

Map 遍歷取值及jstl的取值 學習了&#xff1a;http://blog.csdn.net/yanjiaye520/article/details/17354239 1、Java map的便利取值 Java代碼 收藏代碼 Map<String,String> map new HashMap<String,String>(); map.put("key1", "value1");…

基于CAP組件實現補償事務與冪等性保障

【.NET Core】| 總結/Edison Zhou1補償事務和冪等性在微服務架構下&#xff0c;我們會采用異步通信來對各個微服務進行解耦&#xff0c;從而我們會用到消息中間件來傳遞各個消息。 補償事務某些情況下&#xff0c;消費者需要返回值以告訴發布者執行結果&#xff0c;以便于發布者…

Docker與k8s

前言 隨著k8s 作為容器編排解決方案變得越來越流行&#xff0c;有些人開始拿 Docker 和 k8s進行對比&#xff0c;不禁問道&#xff1a;Docker 不香嗎&#xff1f; k8s 是kubernets的縮寫&#xff0c;’8‘代表中間的八個字符。 其實 Docker 和 k8s 并非直接的競爭對手&#xff…

Linux下啟動tomcat報java.lang.OutOfMemoryError: PermGen space

2019獨角獸企業重金招聘Python工程師標準>>> 一、錯誤信息 java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.jav…

Redis安裝[Windows]

一. redis下載地址: https://github.com/ServiceStack/redis-windows/tree/master/downloads 根據需要的下載對應版本*.zip即可.(我這里是win7x64) 二.使用 1. 下載之后解壓到你相應的目錄下: 1 文件介紹&#xff1a; 2 redis-benchmark.exe #基準測試 3 redis-check-aof.e…

簡練軟考知識點整理-項目啟動過程組

啟動過程組包含定義一個新項目或現有項目的一個新階段&#xff0c;授權開始該項目或階段的一組過程。在啟動過程中&#xff0c;定義初步范圍和落實初步財務資源&#xff0c;識別那些將相互作用并影響項目總體結果的內外部干系人&#xff0c;選定項目經理&#xff08;如果尚未安…

在 ASP.NET Core 中上傳文件

簡介文件上傳是指將媒體文件&#xff08;本地文件或網絡文件&#xff09;從客戶端上傳至服務器存儲。ASP.NET Core 支持使用緩沖的模型綁定&#xff08;針對較小文件&#xff09;和無緩沖的流式傳輸&#xff08;針對較大文件&#xff09;上傳一個或多個文件。緩沖和流式傳輸是上…

Paxos算法詳解

Paxos、Raft分布式一致性算法應用場景一文講述了分布式一致性問題與分布式一致性算法的典型應用場景。作為分布式一致性代名詞的Paxos算法號稱是最難理解的算法。本文試圖用通俗易懂的語言講述Paxos算法。 一、Paxos算法背景 Paxos算法是Lamport宗師提出的一種基于消息傳遞的分…

LeetCode 322. Coin Change

原題 You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, …

Teiid:數據虛擬化Data Virtualization平臺

2019獨角獸企業重金招聘Python工程師標準>>> Teiid介紹 http://teiid.jboss.org/ 數據虛擬化的定義 https://en.wikipedia.org/wiki/Data_virtualization http://www.denodo.com/en/data-virtualization/overview 數據虛擬化的文章 Sick of ETL? Database virtuali…

如何仿造一個websocket請求?

之前兩次singnalr、 websocket實時推送相關&#xff1a;? .NET WebSockets 核心原理初體驗[1]? SignalR 從開發到生產部署避坑指南[2]tag&#xff1a;瀏覽器--->nginx--> server其中提到nginx默認不會為客戶端轉發Upgrade、Connection標頭&#xff0c; 因為為了讓被代理…

【轉】為什么自動車完全不可以犯錯誤

為什么自動車完全不可以犯錯誤 有人跟我講&#xff0c;我對Google的自動車要求太苛刻了。人無完人&#xff0c;所以Google的產品也不需要是完美的&#xff0c;只要“夠好用”就有市場。世界上有那么多糟糕的司機&#xff0c;酒后駕車的&#xff0c;開車時發短信的&#xff0c;打…

從“互聯網+教育”到“教育+互聯網”——互聯網文化基因視域下的審思

作者信息 朱敬/廣西師范大學教育學部教授&#xff0c;教育學博士&#xff0c;博士生導師&#xff1b; 蔡建東/河南大學教育學部教授&#xff0c;教育學博士。 本文摘要 近年來國務院與教育部文件逐漸使用“教育互聯網”一詞&#xff0c;從“互聯網教育”到“教育互聯網”&a…

Node.js Stream - 基礎篇

背景 在構建較復雜的系統時&#xff0c;通常將其拆解為功能獨立的若干部分。這些部分的接口遵循一定的規范&#xff0c;通過某種方式相連&#xff0c;以共同完成較復雜的任務。譬如&#xff0c;shell通過管道|連接各部分&#xff0c;其輸入輸出的規范是文本流。 在Node.js中&am…

Axure RP使用攻略--動態面板的用途(8)

寫了幾個Axure教程之后發現&#xff0c;可能教程的起點有些高了&#xff0c;過分的去講效果的實現&#xff0c;而忽略了axure功能以及基礎元件的使用&#xff0c;那么從這個教程開始&#xff0c;把這些逐漸的展開講解。 關于動態面板 動態面板是axure原型制作中使用非常頻繁的一…

ABP 6.0.0-rc.1的新特性

2022-07-26官方發布ABP 6.0.0-rc.1版本&#xff0c;本文挑選了幾個新特性進行了介紹&#xff0c;主要包括LeptonX Lite默認主題、OpenIddict模塊&#xff0c;以及如何將Identity Server遷移到OpenIddict。據ABP官方公眾號介紹&#xff0c;ABP 6.0.0穩定版的計劃發布日期為2022-…