下面是死鎖情況的一個示例代碼
[java] view
plaincopy
package com.qust.demo.money;
class a {
public synchronized void foo(b b) {
system.out.println(thread.currentthread().getname() + " 進入a的foo");
try {
thread.sleep(200);
} catch (interruptedexception ex) {
ex.printstacktrace();
}
system.out.println(thread.currentthread().getname() + " 試圖調用b的last");
b.last();
}
public synchronized void last() {
system.out.println("a的last()");
}
class b {
public synchronized void bar(a a) {
system.out.println(thread.currentthread().getname() + " 進入b的bar");
system.out.println(thread.currentthread().getname() + " 試圖調用a的last");
a.last();
system.out.println("b的last()");
public class deadlock implements runnable {
a a = new a();
b b = new b();
public void init() {
thread.currentthread().setname("主線程");
system.out.println("進入主線程");
a.foo(b);
public void run() {
thread.currentthread().setname("副線程");
system.out.println("進入副線程");
b.bar(a);
public static void main(string[] args) {
deadlock dl = new deadlock();
new thread(dl).start();
dl.init();
下面是運作結果
[html] view
進入主線程
進入副線程
主線程 進入a的foo
副線程 進入b的bar
副線程 試圖調用a的last
主線程 試圖調用b的last
我們看到,正常情況下,最後還應該列印出“a的last()”和"b的last()",但是因為線程死鎖的原因,是以程式一直在等待執行,沒能正常的執行下去。
在上面的代碼裡面,為什麼會出現死鎖這種情況呢?我們來簡單分析一下。
首先雖然副線程的start()是在主線程的init()之前,但是因為多線程開啟也需要一段時間,是以我們可以看到,是主線程的init()方法執行在前,然後在init()裡面調用了a.foo()。a類和b類中的方法都是同步方法,是以,a的對象和b的對象都是同步鎖。在進入a的foo()之前,線程會對a加鎖,然後線程睡眠200ms,這時候副線程調用b的bar(),同樣的會對b加鎖,然後睡眠200ms。這時候,主線程喚醒,試圖調用b的bar方法,因為是同步方法,是以需要對b加鎖,但是這時候b已經被副線程鎖住了,是以主線程就一直處于阻塞狀态。當副線程喚醒的時候,試圖調用a的同步方法,同樣需要對a加鎖,但是這時候主線程持有a的鎖,并處于阻塞狀态,是以副線程也不能向下執行,大家都在等着對方釋放鎖,是以出現了我們上面說的死鎖的情況。
如果我們把a和b的last()的synchronized去掉,那麼程式在調用last()之前就不需要對對象進行加鎖,也就不會出現死鎖的情況。
因為在工作中還沒有遇到這種情況,是以隻能拿這個執行個體程式講解了。