執行緒的共享(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的方法在同一時間就只能被乙個執行緒訪問了。當方法結束後,鎖釋放。當鎖釋放後,那些因為鎖定而不得其門的多...