58 synchronized同步方法

2022-03-17 05:02:53 字數 1680 閱讀 4623

先看下面**出現的問題:

定義乙個task類,裡面有乙個成員變數和乙個有boolean型別引數的方法,方法內部會根據傳入引數修改成員變數的值。

package

com.sutaoyu.thread;

public

class

task

else}}

建立乙個task物件,將這個物件放到兩個執行緒中,在這兩個執行緒中分別呼叫changenum方法

package

com.sutaoyu.thread;

public

class

synchronizedtest01

};thread t2 = new

thread()

};t1.start();

t2.start();}}

上面的**有可能會出現列印這樣的結果:

thread-1*****begin

thread-0*****begin

thread-1*****66thread-0*****66thread-1*****over

thread-0*****over

正常情況下應該列印出乙個88乙個66,可是上面卻兩個執行緒列印出的兩個66,這樣就出現了執行緒安全的問題,出現這個問題的原因是成員變數儲存在堆記憶體中,兩個執行緒共享堆記憶體,即兩個執行緒可以對同乙個num進行修改。

程式執行分析:

cpu執行t1執行緒,將num修改為88,之後cpu開始執行t2執行緒,將num修改為66,列印出66,cpu開始執行t1執行緒,列印num的值,此時num的值是66。

記憶體**:

比如你要給a,b,c三人發訊息

同步:先給a發,等a回覆後,再給b發,等b回覆後,再給c發,排隊等待

非同步:直接給a,b,c發訊息,中間不需要等某人回覆之後再給其他人發訊息,不用排隊等待

將task中的changenum方法設定為同步的

public

synchronized

void changenum(boolean flag)

在方法上加入synchronized關鍵字,這樣在執行多個執行緒時看哪個執行緒先執行這個方法,假設有t1,t2,t3三個執行緒中都呼叫了changenum方法,t1執行緒先執行了這個方法,那麼t1會先在task物件上面加鎖,加鎖後,別的執行緒就無法執行當前task物件上的changenum方法,直到t1執行結束changenum方法之後,t2,t3中的乙個執行緒才可以執行這個方法,這就保證了在某個時間段內只有乙個執行緒執行changenum方法,解決了執行緒安全問題。

注意:synchronized鎖住的是當前物件,如果t1執行緒和t2執行緒裡面是不同的物件,則不需要同步,因為不會發生執行緒安全問題。如下**:

package

com.sutaoyu.thread;

public

class

synchronizedtest01

};thread t2 = new

thread()

};t1.start();

t2.start();}}

執行緒同步synchronized

synchronized只是保證在同乙個時刻,其他執行緒不能訪問鎖定的資源,但是其他方法或者是變數不能鎖定控制的 synchronized obj 上面語法格式中synchronized後括號裡的obj就是同步監視器,上面 的含義是 執行緒開始執行同步 塊之前,必須先獲得對同步監視器的鎖定。任何時刻...

synchronized同步方法

關鍵字synchronized 如果是在方法內的變數,則無所謂的的變數同步問題。因為在方法內部的變數都是私有的。synchronized如果是加在方法上面,則是對該物件的例項進行同步。如果有兩個執行緒同時對該方法進行操作,則會同步進行。對個例項多個執行緒,不存在同步的問題,那時jvm會生成多個鎖,應...

Synchronized同步方法

非執行緒安全 其實會在多個執行緒對同乙個物件中的例項變數進行併發訪問時發生,產生的後果就是 髒讀 也就是取到的資料其實是被更改過的。1 方法內的變數為執行緒安全的 方法內部的私有變數,則不存在 非執行緒安全 的問題,所得結果也就是 執行緒安全 的。2 例項變數非執行緒安全 如果多個執行緒共同訪問乙個...