xqstation
xqstation
2008-08-07 08:54

请教关于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在取得锁的时候取不到才对吧。

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

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

2条回答

  • iteye_14762 iteye_14762 13年前

    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]

    点赞 评论 复制链接分享
  • aidiyuxin aidiyuxin 13年前

    你给两个方法都加上synchronized

    点赞 评论 复制链接分享

相关推荐