執行緒安全(ThreadSafety)

2022-02-14 14:34:42 字數 2843 閱讀 9474

這節講一下執行緒安全的例子,以及如何解決執行緒安全問題。

上節提到了執行緒安全的問題,說了乙個例子,1000個人搶100張票,這節就從此案例著手,下面先看一下**實現:

private

static

int tickets = 100

;static

void main(string

args)

private

static

thread buyticket()

---------------->買了一張票,票號為:");

tickets--;

}});

thread.isbackground = true

;

return

thread;

}

現有三個執行緒,同時訪問共享資源tickets,我們先來看一下執行結果:

100賣出了三次,這就是很明顯的執行緒安全問題,也就是說,他們都同時進入到了while塊中,同時拿到了tickets為100的值,所以我們解決執行緒安全問題,就要從此處下手,讓執行緒訪問共享資料的時候,同一時刻只能有乙個執行緒去訪問。

lock鎖

解決執行緒安全的方法就是加鎖(同步鎖,互斥鎖),現在將**改一下,使其執行緒安全:

private

static

object o = new

object

();private

static

int tickets = 100

;static

void main(string

args)

private

static

thread buyticket()

---------------->買了一張票,票號為:");

tickets--;}}

}});

thread.isbackground = true

;

return

thread;

}

while塊中,我加上了乙個lock塊,它需要乙個object型別的引數作為同步物件,被lock塊包住的**,在同一時間只能有乙個執行緒訪問,看一下執行結果(方便檢視,我將數量改為了30):

可以看到,執行緒安全問題已經解決。我們再來看一下同步物件:

lock (object obj){}
lock塊,它需要乙個object型別的引數作為同步物件,也就是說,執行緒走到這裡,會先看看這個同步物件是不是被占用著,如未被占用,則進入,否則執行緒阻塞,直到同步物件被解除占用,注意,多個執行緒,要使用乙個同步物件,不然,乙個執行緒訪問乙個單獨的同步物件,那跟沒加鎖一樣,另外,根據多型性,這個同步物件可以是任意物件,因為object是所有類的父類,但是string型別不可用,這點要注意。

monitor鎖

monitor鎖的用法跟lock差不多,請看如下**:

while (true

)---------------->買了一張票,票號為:");

tickets--;

}monitor.exit(o);

}

monitor將**塊改為了enter和exit兩個方法,也是需要同步物件。

互斥鎖是乙個互斥的同步物件,同一時間有且僅有乙個執行緒可以獲取它。跟monitor一樣,也是通過兩個方法控制的,具體用法請看下面的**:

private

static mutex mutex = new

mutex();

private

static

thread buyticket3()

---------------->買了一張票,票號為:");

tickets--;

}mutex.releasemutex();

//解除

} });

thread.isbackground = true

;

return

thread;

}

死鎖如果濫用執行緒鎖,容易出現死鎖的問題,什麼是死鎖呢?比如有兩個執行緒t1,t2,它們共用兩個同步鎖l1,l2,t1先走l1,t2先走l2,t1下一步走l2,t2下一步走l1,這樣這兩個執行緒各種握著對方的下一步鎖,一直阻塞最後誰也走不了。或者使用像monitor這樣的鎖,突然出現異常,exit方法來不及執行,也會死鎖,其它的執行緒也會一直阻塞。下面來演示一下:

private

static

thread buyticket2()

---------------->買了一張票,票號為:");

tickets--;

}monitor.exit(o);}}

catch

{}

});thread.isbackground = true

;

return

thread;

}

執行結果如下:

因為一開始執行緒就直接死鎖,其它的執行緒無法繼續執行,會一直阻塞。

執行緒安全與執行緒不安全

執行緒安全是針對多執行緒來講的,如果所使用的公用變數在多執行緒下沒有被保護機制時,變數結果會和理論值不一致,這樣就叫作執行緒不安全,相反公用變數在保護機制下工作,就不會出現 隨機 變化,這時叫執行緒安全。執行緒安全 在多執行緒中使用時,不用自已做同步處理.執行緒不安全 在多執行緒中使用時,必須做執行...

執行緒安全與執行緒不安全

執行緒安全是針對多執行緒來講的,如果所使用的公用變數在多執行緒下沒有被保護機制時,變數結果會和理論值不一致,這樣就叫作執行緒不安全,相反公用變數在保護機制下工作,就不會出現 隨機 變化,這時叫執行緒安全。執行緒安全 在多執行緒中使用時,不用自已做同步處理.執行緒不安全 在多執行緒中使用時,必須做執行...

Java執行緒安全和非執行緒安全

arraylist是非執行緒安全的,vector是執行緒安全的 hashmap是非執行緒安全的,hashtable是執行緒安全的 stringbuilder是非執行緒安全的,stringbuffer是執行緒安全的 什麼是執行緒安全?執行緒安全和非執行緒安全有什麼區別?分別在什麼情況下使用?非執行緒安...