多執行緒與高併發之執行緒安全

2021-10-23 08:02:04 字數 2028 閱讀 2723

使用兩個執行緒模擬火車站兩個視窗同時買票的場景

定義乙個全域性變數count=100,定義乙個執行緒run方法中實現買票的模擬操作(count–),最後在測試方法中定義兩個執行緒並啟動,實現買票操作;**如下:

public

class

threadtest01

implements

runnable

catch

(interruptedexception e)

saleticket()

;}}private

void

saleticket()

/** * 使用兩個執行緒模擬兩個視窗賣火車票

*/public

static

void

main

(string[

] args)

}

這個時候的執行結果:

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

從以上的結果我們可以看出有3個問題:

​ 為什麼會出現這樣的情況呢?主要是因為共享的變數是執行緒不安全的,這樣多個執行緒在操作同乙個變數的時候就會出現操作衝突的情況。

如何解決多執行緒的執行緒安全問題:

使用synchronized關鍵字,使得多執行緒同步,或者使用lock

什麼是多執行緒同步?

當多個執行緒使用共享變數的時候,相互不受干擾

如何使用synchronized來保證執行緒安全,只要將有執行緒安全問題的**使用synchronized包裹起來即可:

synchronized

(同資料)

或者使用:

synchronized

(物件)

//這個物件可以為任意物件

private

synchronized

void

saleticket()

使用同步**塊的方式來解決執行緒安全問題,saleticket方法修改後**如下:

private

void

saleticket()

}

這個時候我們再來看看執行結果是怎麼樣的?

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

咦…"視窗賣了第張票"是什麼鬼,外面的while迴圈不是已經判斷了count>0了嗎?這是因為我們synchronized的關鍵在加在saleticket裡面,當票剩下一張的時候,有可能thread1、thread2執行緒都已經執行到saleticket()方法,在等待釋放鎖,所以在乙個執行緒執行完count--之後另外乙個執行緒進入該方法就出現超賣的情況。我們將saleticket方法改造下:

private

void

saleticket()

else

}}

我們再來看看執行結果:

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

視窗賣了第張票

票已售完...

..

多執行緒與高併發

blocked 鎖池 timed waiting 定時等待 waiting 等待 terminated 禁止指令重排序 記憶體屏障 在單例雙重檢查中,不加會出現使用半初始化的值,也就是還未附初始值,指令重排導致的 類載入與指令重排的知識 public class spinlock while fla...

多執行緒高併發

修飾靜態方法鎖的是class,非靜態鎖方法鎖的是this,只有拿到這個物件才可以繼續執行 synchronized是可重入鎖 執行緒1的方法1呼叫執行緒2的方法2,判斷是同一把鎖,在同乙個執行緒,可以呼叫。synchronized的鎖公升級 hotsport 鎖公升級過程 保證執行緒可見性 mesi...

多執行緒高併發

個人總結,帶有個人主觀,請選擇性 1,實現 runable 2,使用 thread 3,執行緒池建立 executorse newcachedthreadpool 其實哪有那麼多建立方式,本質上都是實現了runable 介面。只列出大部分使用的方法,並未代表所有執行緒方法,後續會新增實際的例子,以供...