執行緒的共享 synchronized

2021-09-25 23:23:39 字數 3206 閱讀 5184

執行緒的共享(synchronized)

synchronized :修飾方法,或是作用於塊,但是無論如何,我們都應該視其為乙個禁入條件,

也就是說,synchronized應該使用的場景是:當乙個方法有可能被並行執行時,

而其內部有對資料進行增刪改的操作時,需要被保證其進入條件,

此時可選擇使用,synchronized**塊 或是 synchronized 方法。

形象生動地:

我們可以視其synchronized為乙個鎖,

其包裹內容視作房間,整體看做是外面帶有鎖的房間

「當乙個方法有可能被並行執行時」:

這意味著:

如果方法為乙個例項方法,那麼當我們使用該類同乙個物件,

並且有可能並行地執行該例項方法時,我們才可能使用synchronized

如果我們是序列操作,又或者對於每乙個物件,使用其自身的這個例項方法,

那麼我們是不需要新增synchronize。

同理,當方法為類方法時,也作同樣考慮,但此時主語為該類本身,而非其物件行為

「作用於塊」:

一般而言將物件this當資源:

synchronized(this)

「修飾方法」:

public synchronized void go()

舉個例子說明:

當同一物件通過自身例項方法對數值做出加減時,要保證僅有這個物件同時僅進入乙個。

1.建立callable介面實現類,重寫call,定義synchronized方法,和普通方法

class callthread implements callable

@override

public integer call() throws exception catch (interruptedexception e)

} else

} return integer.valueof(5);

}

public  synchronized void go() throws interruptedexception 

}

public void go1() throws interruptedexception 

}

public void go2() throws interruptedexception 

}}

public void go3() throws interruptedexception 	}	

} } //這個括號是整個callthread類的

2.通過使用executors.newcachedthreadpool()建立executorservice類物件,

再由executorservice類的物件,submit()同乙個callable實現類的物件,

內部呼叫非synchronized方法,可以觀察到結果顯示

class mediation
mediation mediation = new mediation();

callthread callthread = new callthread(mediation);

executorservice eservice = executors.newcachedthreadpool();

futurefuture = eservice.submit(callthread);

futurefuture1 = eservice.submit(callthread);

thread.sleep(1000);

callthread.flag = false;

system.out.println(future.get(1000,timeunit.milliseconds));

system.out.println(future1.get(1000,timeunit.milliseconds));

eservice.shutdown();

if(!eservice.awaittermination(8*1000, timeunit.milliseconds))

3.我們可以觀察到輸出結果是:

go1():且發生了get()引發的timeoutexcepiton

pool-1-thread-1 has num: 499

pool-1-thread-1 has num: 498

pool-1-thread-2 has num: 500

可以推測出來:thread2,thread1同時到達判斷%2的位置,並且同時判斷成功

但是thread2先完成了減一操作,thread1緊追其後,但此時1獲得的已經是減了1的499,

而499是不滿足於先前的%2判斷的,這裡是乙個錯誤。另乙個錯誤是,

thread1完成了499的減一操作後,再一次使數值%2判斷成功,此時,

不管是thread1,thread2,都有機會在間隙中進入執行,並成功,

但是如果再往後,並非都能繼續借助間隙來繼續執行,

而應該是會存在時間片的長度限制。

4.嘗試使用go(),即使用了synchronized包裹的go1函式,觀察結果:

pool-1-thread-1 has num: 500

5 5後面的5,5,為返回值,第一條非常符合,應該threa1,thread2,僅有1個進去執行,

得到了500,減為499,thread1,或是thread2沒有辦法在499的情況下進入執行,

因此僅僅為乙個500。

5.嘗試使用synchronized(this)**塊:–go2()

pool-1-thread-1 has num: 500

5 5輸出結果和4一致,是正確的。

6.嘗試使用:鎖定其他資源的go3(),觀察其輸出結果

synchronized(integer.valueof(mediation.num)

pool-1-thread-2 has num: 500

pool-1-thread-2 has num: 498

pool-1-thread-1 has num: 499

輸出結果和3一致,是錯誤的。

Java執行緒同步問題synchronized

android usb 讀寫以前都是一讀一寫,但有些機器會出問題。就採用讀寫非同步的方法。使用物件鎖,object自帶的,然後使用object的方法wait和notify notifyall 使用方法簡單,記錄下 public synchronized int lra setregister int...

Java學習之執行緒鎖 synchronized

同步 併發 多個執行緒訪問同乙份資源 確保資源安全 執行緒安全 synchronized 同步 1 同步塊 synchronized 引用型別 this 類.class 2 同步方法 public synchronized void test public class testsyn class t...

執行緒的共享互斥

所謂的執行緒的共享互斥 就是指乙個例項的一些方法在同一時刻,只能被乙個執行緒執行。實現方式如下 最簡單的辦法是將方法加上synchronized關鍵字,這樣,這個例項所有加了synchronized的方法在同一時間就只能被乙個執行緒訪問了。當方法結束後,鎖釋放。當鎖釋放後,那些因為鎖定而不得其門的多...