日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java 多线程不安全_多线程并发为什么不安全

發布時間:2024/8/1 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 多线程不安全_多线程并发为什么不安全 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、線程安全定義

?定義:

?多個線程訪問同一個對象時,如果不用考慮這些線程在運行時環境下的調度和交替執行,也不需要進行額外的同步,或者在調用方進行任何其他操作,調用這個對象的行為都可以獲得正確的結果,那么這個對象就是線程安全的。

該定義由Brian Goetz在《Java Concurrency In Practice》(Java并發編程實戰)中定義;被百度百科、《深入理解Java虛擬機2》引用;

二、并發安全問題

?大概很多人都知道一點為什么在多線程并發時會不安全,多線程同時操作對象的屬性或者狀態時,會因為線程之間的信息不同步,A線程讀取到的狀態已經過時,而A線程并不知道。所以并發安全的本質問題在于線程之間的信息不同步!

?分析并發不安全的現象,再一層層展示其原理。

2.1、 競態條件

?定義:

?在并發編程中,由于不恰當的執行時序而出現不正確的結果。

?案例:

?這是一個線程不安全的方法,我們的期望是每次獲取queryTimes都會將queryTimes的值+1;但是當多線程并發訪問時,它的工作情況并不如我們所預想的那般;

static int queryTimes = 0;

public static int getTimes(){

queryTimes = queryTimes +1;

return queryTimes;

}

?

案例圖解:

圖解說明:

當線程A進入方法獲取到queryTimes=17時,線程B正準備進入方法;

當線程B獲取到queryTimes=18時,線程A還未處理值;

當線程A處理queryTimes+1 = 18后,線程B隨即處理queryTimes+1 = 18;

此時線程A才將處理后到結果寫入queryTimes,隨后B也將18寫入到queryTimes;

?根據上述,我們知道當競態條件存在時,多個線程可能同時或者幾乎同時讀取到某個狀態(值),然后將處理后到值進行寫入,此時我們可以說發生了數據的"臟讀"

?總結:

?競態條件是指多線程同時對數據進行改變,讀取到臟數據或寫入錯數據;

2.2、 重排序、有序性、可見性

2.2.1、 指令重排序

?定義:

?計算機為了性能優化會對匯編指令進行重新排序,以便充分利用硬件的處理性能。

?

?案例:

int a;

int b;

int c;

...略...

a = 1; // 步驟a

b = 2; // 步驟b

c = a + b; // 步驟c

?案例圖解:

?案例分析

雖然代碼順序是步驟a、步驟b、步驟c

但是從時間上以上三種情況都有可能

原因是步驟a和步驟b并沒有依賴關系

所以為了能快點執行,計算機會調整步驟a和步驟b的順序

因為步驟c依賴于步驟a和步驟b,所以重排序也會在a和b之后

2.2.2、 有序性

?定義:

?在Java中,單線程總是順序執行的!

?當編譯器和處理器重排序時,必須保證,不管怎么重排序,單線程的執行結果不能被改變

2.2.3、 可見性

?定義:

?多線程中,若線程A中進行的每一步都可以被線程B觀測到,則稱線程A對線程B具有可見性。

?線程B不僅可以看到線程A處理的結果,還能準確的知道在處理過程中,每一個狀態的改變,已經狀態改變的順序;

?Java線程的通訊是透明的,線程之間不可以直接進行信息交換,所有的通訊必須同內存共享!所以多線程是天然不可見的,就是說如果不主動干涉的話,線程之間不可見,為什么呢,因為線程雖然第一步處理步驟a,第二步處理步驟b,但是先將步驟b的結果寫入主內存,后將步驟a的結果寫入主內存,則對觀測線程來說,首先看到的是步驟b的結果,然后才是步驟a的結果!

2.3、內存模型

?Java線程模型由主內存和工作內存組成;

如圖:

?說明:

工作內存和主內存兩部分一起組成Java線程的內存模型

工作內存是屬于線程的,不同線程的工作內存之間不可共享,不可通訊

工作內存通過Load操作從主內存中讀取數據,通過Save操作將數據寫入主內存

線程之間的通訊:本質上是指通過主內存的數據共享

?解釋可見性:

?如圖,Java線程之間是不可見的,因為線程的操作都在它本身的工作內存中完成,完成后的數據再寫入主內存。我們稱線程之間不可見是因為線程本身沒有直接通訊機制;但是線程可以通過主內存進行數據交換,也可以說線程之間可通過內存通訊;

?

?解釋有序性和無序性:

?單線程有序,是因為單線程的數據操作本身在它私有的工作內存中進行,不管如何重排序,單線程的執行結果不可被改變,所以寫入主內存的結果總是正確的。

a = 1; // 步驟a

b = 2; // 步驟b

c = a + b; // 步驟c

?線程在被觀測時無序,因為當線程A中順序執行 a = 1、b = 1時,并不能保證先將a的值寫回主內存,完全有可能先將b的值寫入主內存,這是不可預測的。所以在線程B中觀察線程A的處理順序,是非常不可靠的!

因為線程之間只能通過主內存來進行數據交換,所以線程B讀到a=0,b=1時,在線程A中可能已經時a=1,b=1。只不過還沒有及時到將a的值寫入主內存。這樣線程B可能誤以為線程A先執行的是b=1;

三、總結

?多線程為什么不安全?現在應該有答案了!究其根本,是因為線程之間無法準確的知道互相之間的狀態。那么如何使得多線程安全呢,從內存角度來講,保證線程的工作內存之間的可見性和有序性,是多線程并發安全的基礎。例如volatile關鍵字和synchronized關鍵字,我們除了從作用上了解他們,還可以從更深層的內存語義上理解,他們之所以能夠一定程度的解決線程安全問題,是因為他們約束了一定的內存處理方式!

總結

以上是生活随笔為你收集整理的java 多线程不安全_多线程并发为什么不安全的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 一起草最新网址 | 亚洲AV无码国产精品 | 黄色精品一区 | 成人欧美一区二区三区黑人 | 亚洲天堂婷婷 | 四色最新网址 | 亚洲欧洲天堂 | 日本老肥婆bbbwbbbwzr | 天天干夜夜 | 欧美成人a∨高清免费观看 国产精品999视频 | 欧美日韩精品三区 | 欧美麻豆视频 | 男人的天堂网在线 | 亚洲视频在线免费播放 | 亚洲综合网av | 蜜桃视频在线观看一区 | 久草视频免费 | 亚洲人掀裙打屁股网站 | 亚洲国产欧美在线 | 少妇性生活视频 | 国产成人一区在线观看 | 亚洲人免费视频 | 亚洲女同一区二区 | 欧美极品少妇xxxxⅹ裸体艺术 | 电影《走路上学》免费 | 中文字幕欧美人妻精品一区蜜臀 | 成人动漫在线观看 | 久综合网| a在线看 | 潮喷失禁大喷水aⅴ无码 | 欧美日韩在线视频免费播放 | 成人亚洲在线 | 国产成人高清在线 | 双乳被四个男人吃奶h文 | 三叶草欧洲码在线 | 看av网址 | 欧美一区二区三区视频 | 一区二区视屏 | 黄色理伦片| 伊人三区| 日韩欧美国产中文字幕 | 国产精品久久久久久免费播放 | 不卡一区二区在线观看 | 日韩久久久 | 三年中文免费观看大全动漫 | 中文字幕一区二区三区人妻 | 成人在线视频网站 | 亚洲天堂免费av | 精品无码久久久久久久久久 | 男女互操在线观看 | 成年人av网站 | 黄色av免费网站 | 欧美人与动物xxxxx | 日韩精品欧美精品 | 在线不卡毛片 | 久久精品99 | 日韩欧美视频一区二区三区 | 亚洲成人第一区 | 夜夜春夜夜爽 | 欧美人妻精品一区二区三区 | 亚洲午夜在线视频 | 亚洲无码一区二区三区 | 国产黄色大片免费看 | 欧美性做爰猛烈叫床潮 | 毛片免费一区二区三区 | 少妇性l交大片免费观看 | 一级片免费在线观看 | 男女网站在线观看 | 成年网站免费在线观看 | 国产一级二级三级 | 影音先锋成人资源网 | 快射视频在线观看 | 国内自拍视频在线播放 | 色爱综合区 | 国产免费不卡av | 琪琪射 | 黄色一级a毛片 | 国产三级在线免费 | 久久久久久电影 | 亚洲va久久久噜噜噜久久天堂 | 97视频在线 | 色中文在线 | 特级少妇| 亚洲精品国产电影 | 成年人视屏 | 色播激情网 | 日韩av在线高清 | 夜夜躁日日躁狠狠久久av | 伊人黄网 | 久久爱成人 | 人人爱人人艹 | 精品人妻伦一二三区久久 | 另类尿喷潮videofree | xxxx日本黄色 | 久久亚洲免费视频 | 国产区小视频 | 99国产精品无码 | 伊人av综合 | 伊人福利在线 |