大家可能平時玩電腦,可以同時掛qq啊,玩遊戲啊,開啟文字啊,等等。這裡,我們假設是單塊cpu。也就是俗稱的單核cpu。
大家可能會覺得這些軟體,這些執行緒是同時執行的,
其實不然,其實在任何一種情況下,電腦都只執行乙個執行緒!
只是因為這個單塊的cpu內部為我們劃分了很多很多的時間塊,
而這個時間的劃分是以納秒為單位的,也就是說,這個10納秒我執行這個執行緒,下個10納秒執行另外乙個執行緒(或者又被上乙個執行緒搶到了(只是被上乙個執行緒搶到的概率小,這是cpu排程器的演算法決定了的),它會慢慢平衡的,不可能一直讓某乙個執行緒一直搶占cpu排程器資源),所以說,它執行並不是連續的,只是間隔時間太短,我們感覺不出來而已!!!
1)多個執行緒共用同乙個物件鎖,互相等待。
兩個執行緒共用乙個鎖,乙個執行緒拿著鎖來呼叫另外乙個執行緒,於是出現了死鎖情況!
package thread.deadlock.lock1;
/** * 簡單的類
*@author 陳浩翔
* * 2016-4-22
*/public
class
s
package thread.deadlock.lock1;
/** * 含有main方法的類
*@author 陳浩翔
* * 2016-4-22
*/public
class
deadlock1
}
package thread.deadlock.lock1;
/** * threadb類
*@author 陳浩翔
* * 2016-4-22
*/public
class
threadb
implements
runnable
@override
public
void
run() }}
package thread.deadlock.lock1;
/** * threada類
*@author 陳浩翔
* * 2016-4-22
*/public
class
threada
implements
runnable
@override
public
void
run() catch (interruptedexception e)
system.out.println("s.a = " + s.a);}}
}
執行結果只有一種情況,一定鎖死!
2)互相持有對方所需的資源(即每個執行緒都需要同時拿到多個資源才能繼續執行,而多個執行緒都處於:各持有一部分,在等待另一部分。)
package thread.deadlock.lock2;
/** * 資源類1
*@author 陳浩翔
* * 2016-4-22
*/public
class
s1
package thread.deadlock.lock2;
/** * 資源類2
*@author 陳浩翔
* * 2016-4-22
*/public
class
s2
package thread.deadlock.lock2;
/** *
*@author 陳浩翔
* * 2016-4-22
*/public
class
deadlock2
}
package thread.deadlock.lock2;
/** * threada---a執行緒執行**類
*@author 陳浩翔
* * 2016-4-22
*/public
class
threada
implements
runnable
@override
public
void
run() //釋放鎖s2
system.out.println("執行緒a釋放了鎖s2");
}//釋放鎖s1}}
package thread.deadlock.lock2;
/** * threadb---b執行緒執行**類
*@author 陳浩翔
* * 2016-4-22
*/public
class
threadb
implements
runnable
@override
public
void
run() //釋放鎖s1
system.out.println("執行緒b釋放了鎖s1");
}//釋放鎖s2}}
這個情況下的死鎖會出現2中情況::
第一種:沒有死鎖:
這種情況的出現是因為可能a執行緒或者b執行緒搶到了cpu資源,一次就全部執行完了,這樣,就不會出現死鎖!
第二種:出現了死鎖:
假如a執行緒拿到了s1的鎖,還沒有拿到s2的鎖,
這個時候s2的鎖被b執行緒拿到了,b執行緒就開始等待s1鎖,而s1鎖在a執行緒手上,a執行緒就等s2鎖啊,b執行緒就等s1鎖,,,於是,出現了死鎖!
大家可以看到,這個死鎖的情況下,程式並沒有停止執行的,那個程式執行的紅方塊標誌還亮著呢!
前面那圖沒有出現死鎖的情況下,程式執行一下就輸出完了,紅方塊是暗的!
死鎖的解決
(死鎖並沒有解決的方案,只能從源頭上去避免!)
要從設計方面去解決避免,即在設計時就考慮不能出現死鎖。
羅列出所有臨界資源,畫分布圖,從圖中觀察其中的死鎖情況,改變其中執行緒的(臨界)資源的獲取方式。
設計原則:盡量讓程式中少出現臨界資源。
wait/notify 和 sleep方法
wait和notify只能在它們被呼叫的例項的同步塊內使用,而sleep()到處都可以用。
wait()和sleep()最大的區別:sleep()不釋放物件鎖,而wait()會釋放,因此從效率方面考慮wait()方法更好。
同步設計的基本原則
◎ 同步塊中(synchronized修飾)的**越小越好!
◎ 同步塊中不要寫阻塞性**(如,inputstream.read() )!
◎ 在持有鎖的時候,不要對其它物件呼叫方法。(如果做到,可以消除最常見的死鎖源頭。)
同步概述
◎同步的原理:將需要同步的**進行封裝,並在該**上加了乙個鎖。
◎同步的好處:解決多執行緒的安全問題。
◎同步的弊端:會降低效能。
◎同步的前提:必須要保證有多個執行緒且它們在同步中使用的是同乙個鎖。
java多執行緒之 死鎖
當兩個或多個執行緒競爭試圖獲取對方持有的同步鎖時,它們都會處於阻塞狀態,除非某個執行緒主動釋放自己所持有的同步鎖,這時,死鎖就出現了。用下面這張圖很好理解 如圖,執行緒thread1和thread2都有兩個同步方法operation1 operation2 operation1 中會呼叫operat...
多執行緒之死鎖
1 死鎖發生的場景 有時候兩個或者多個執行緒需要訪問同乙份資源,這裡就涉及到執行緒同步的問題 thread1 synchronized object1 thread2 synchronized object2 看看上面的例子,兩個執行緒各自都有想要訪問對方的想法,可是雙方都不願意放手,就像a拿到了開...
多執行緒之死鎖
死鎖。同步中巢狀同步。你有一根筷子,我有一根筷子,我要吃飯,你不給我,我不給你,誰都吃不著飯,死鎖發生,但是死鎖不一會發生,也會存在和諧的狀態,就是你把筷子給我,我吃一口,我再把筷子給你,你再吃一口 class ticket implements runnable else while true s...