请教关于synchronized死锁的问题

各位好。那个分类里面,实在是不知道该分到哪。

最近在学习多线程方面的知识,
然后发现以前所想的有些误解。
关于synchronized method:
以前认为定义为synchronized的method的lock是跟着method走的,经过学习发现是跟类的实例的。
如,有一个类,有两个方法,method1和method2,然后创建该类的实例,让两个Thread对该实例引用并分别调用这两个方法,执行的时候这两个方法是同步的,也就是需要其中一个执行完了,才会执行下一个。

以下给出代码,我的问题在最后。

先是Interface
[code="java"]
public interface DemoInterface {
public void method1();
public void method2();
}
[/code]

具体实现类
[code="java"]
public class DefaultClass implements DemoInterface {
public synchronized void method1(){
System.out.println("DefaultClass.method1 begin");
int o = 0;
for(int i=0; i<100000000; i++){
o+=i;
}
System.out.println("DefaultClass.method1 end");
}

public synchronized void method2(){
    System.out.println("* DefaultClass.method2 run");
}

}
[/code]

两个Thread,分别执行method1和method2
[code="java"]
public class TestThread1 extends Thread {
DemoInterface dc;
public TestThread1(DemoInterface dc){
this.dc = dc;
}
public void run(){
this.dc.method1();
}
}
[/code]
[code="java"]
public class TestThread2 extends Thread {
DemoInterface dc;
public TestThread2(DemoInterface dc){
this.dc = dc;
}
public void run(){
this.dc.method2();
}
}
[/code]

最后是main
[code="java"]
public class MainRun {
/**
* @param args
*/
public static void main(String[] args) {
DemoInterface dc;
dc = new DefaultClass();
TestThread1 t1 = new TestThread1(dc);
TestThread2 t2 = new TestThread2(dc);
t1.start();
t2.start();
}
}
[/code]

执行的结果是:
DefaultClass.method1 begin
DefaultClass.method1 end

  • DefaultClass.method2 run

如果把method2的synchronized定义去掉那么结果将是:
DefaultClass.method1 begin

  • DefaultClass.method2 run DefaultClass.method1 end

问题:
在有synchronized定义的情况下,method1执行时是lock的,直到执行完成才unlock,然后才能执行method2,
但是我在method1中调用method2为什么不是死锁呢?
应该是method1还没执行完,method2在取得锁的时候取不到才对吧。

哪位可以修改以上程序弄个死锁状态出来么?

1, 你在method1中调用method2时, 因为两个方法都是在当前线程中运行, 也就是在同一个线程中运行, 而当前线程是持有锁的, 所以两个方法都会执行, 不会产生死锁
2, 下面是把你的例子修改了一下:
[code="java"]public class DefaultClass implements DemoInterface {

private Object deadLock = new Object();

public synchronized void method1() {
    synchronized (deadLock) {
        System.out.println("DefaultClass.method1 begin");
        int o = 0;
        for (int i = 0; i < 100000000; i++) {
            o += i;
        }
        System.out.println("DefaultClass.method1 end");
    }

}

public void method2() {
    synchronized (deadLock) {
        method3();
    }       
}

public synchronized void method3() {
    System.out.println("* DefaultClass.method2 run");
}

}[/code]
这个代码和下面的代码是等效的:
[code="java"]public class DefaultClass implements DemoInterface {

private Object deadLock = new Object();

public void method1() {
    synchronized (this) {
        synchronized (deadLock) {
            System.out.println("DefaultClass.method1 begin");
            int o = 0;
            for (int i = 0; i < 100000000; i++) {
                o += i;
            }
            System.out.println("DefaultClass.method1 end");
        }
    }
}

public void method2() {
    synchronized (deadLock) {
        synchronized (this) {
            System.out.println("* DefaultClass.method2 run");
        }
    }
}

}[/code]
我列出这两块代码, 是为了向你说明:
[code="java"]public void method1() {
synchronized (this) {
System.out.println("DefaultClass.method1 begin");
int o = 0;
for (int i = 0; i < 100000000; i++) {
o += i;
}
System.out.println("DefaultClass.method1 end");
}
}[/code]和
[code="java"]public synchronized void method1() {
System.out.println("DefaultClass.method1 begin");
int o = 0;
for (int i = 0; i < 100000000; i++) {
o += i;
}
System.out.println("DefaultClass.method1 end");
}[/code]是等效的, 锁的都是当前实例(好像说的太啰嗦了, 哈哈!).
3, 测试时多用几个线程:
[code="java"]public static void main(String[] args) {
DemoInterface dc;
dc = new DefaultClass();
for (int i = 0; i < 100; i++) {
new TestThread1(dc).start();
new TestThread2(dc).start();
}
}[/code]

你给两个方法都加上synchronized