多執行緒帶來的風險 執行緒安全

2021-10-04 00:03:05 字數 1917 閱讀 3530

1、多執行緒的三大特性

案例描述:

電影院有三個視窗,售兩種票共 100 張,輸**票情況

class

sellticket

implements

runnuble

catch

(interruptexception e)

system.out.

println

(thread.

currrentthread()

.getname()

+"正在出票"

(ticket--)+

"票數");

}}}}

public

class

sellticketdemo

}

分析:每次輸出的結果不同,此次結果出現了兩種不安全的情況:相同的票和負數票的情況

那麼那些問題會引起執行緒的不安全?

1>是否是多執行緒環境

2>是否有資料共享

3>是否有多個操作於共享資料

而在以上的**中前兩條是完全符合的,問題在於是否有多個操作共享資料?

注意 ticket-- 操作;cpu並不是簡單的執行了一次減一,而是進行了三步:

1> 從記憶體讀取變數到 cpu

2> 修改變數

3> 寫回記憶體

出現相同的票(cpu的操作原子性決定的)

cpu 的每一次執行都是原子性(最簡單基本)的操作,比如 ticket–其實並不是一次操作;

首先記錄tiket以前的值 50

接著執行 tiket-- 的操作

然後輸出以前的值 50 t1輸出,就在這之間可能 t2 就來了(併發/並行),則 t2 也輸出一樣的了

tiket 的值變成 49

出現負數票的情況,就是在休眠的時候(隨機性和延遲導致)

t1 、t2、t3 恰好都在 100 毫秒內分別進來了,所以三個都會執行

所以最壞情況下:

正在**第 1 張票 ticket = 0

正在**第 0 張票 tiket = -1

正在**第 -1 張票 tiket = -2

常見的非原子性操作:

n++;–n 從記憶體讀取變數到cpu,修改變數、寫回記憶體

物件的new操作 分配物件的記憶體、初始化物件、將物件賦值給變數

2、synchronized 實現執行緒同步

synchronized

(物件)

//注意同步可以解決安全問題的根本原因在物件上,該物件如同鎖的功能

//多個執行緒必須是同一把鎖

//鎖的物件是任意物件

1> 特點:多個執行緒是前提、多個執行緒使用的是同乙個鎖物件

2> 好處:解決了多執行緒的安全問題

3> 弊端:當執行緒相對較多時,每個執行緒都會去判斷同步上的鎖,這是很耗費資源的會降低程式的執行效率

修改後執行緒安全

public

class

sell_ticket

implements

runnable

catch

(interruptedexception e)

system.out.

println

(thread.

currentthread()

.getname()

+"正在**"

+(ticket--)+

"票");}

}}}}

public

class

sell_ticketdemo

}

3 執行緒帶來的風險

1 死鎖 產生死鎖的原因 關於死鎖出現的必要條件 這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,這也為我們實際應用中定位死鎖問題,提供了路由。不加鎖,兩線程訪問,變數訪問示例 當兩個執行緒讀寫相同變數時,執行緒a讀取變數然後給予變數賦予乙個新的值,但是寫操作需要兩個儲存器週期。當執...

多執行緒 執行緒安全

原因 當多個執行緒同時共享,同乙個全域性變數或靜態變數。做寫的操作時,可能發生資料衝突問題,也就是執行緒安全問題。但是做讀操作是不會發生資料衝突問題。解決方案 方式一 內建鎖synchronized synchronized保證執行緒原子性,當執行緒進入方法的時候,自動獲取鎖,一旦鎖被其它執行緒獲取...

多執行緒 執行緒安全

public class unsafethread t.start while thread.activecount 1 system.out.println sum 1 從主記憶體中講sum變數複製到執行緒的工作記憶體 2 在工作記憶體中修改變數 1操作 3 將sum變數從執行緒的工作記憶體寫回到...