class TestSyncDemo 
{
private StringBuffer sb=new StringBuffer("abc");
public static void main(String[] args) 
{
TestSyncDemo tsd=new TestSyncDemo();
MyThread mt=new MyThread(tsd.sb);
mt.start();
/*try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}*/
synchronized(tsd.sb){
try{
mt.join();
System.out.println("sb"+tsd.sb);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
class MyThread extends Thread
{
private StringBuffer sb;
public MyThread(StringBuffer sb){
this.sb=sb;
}
public void run(){
synchronized(sb){
   System.out.println(sb);
}
}
}
上面是我写的测试死锁的代码,我现在对main和mt线程的执行顺序有点疑惑,下面是我的疑惑,请各位高手帮忙解答:
刚开始应该执行的是main线程,执行到mt.start()时,mt线程有可能会马上执行吗(假设没有mt.join())?还是得等到main方法都执行完了才执行?如果加了mt.join()代码,是否一定会发生死锁?

解决方案 »

  1.   

    1、不是马上执行也不是main执行完了才执行
    start只是将mt线程加入到jvm的线程调度队列,分配时间片,它就会running
    2、这个代码不定会死锁mt.start()后可能迅速得到cpu时间而在瞬间完成打印,这时mt线程死掉
    随后主线程是调度中的唯一线程……
    3、就算去掉注释代码,照样没有死锁,死锁的可能性更小
    4、你可以这样造死锁
    Thread A:
    syn(obj1){
       sleep(100);
       syn(obj2){
          sysout...
       }
    }Thread B:
    syn(obj2){
       sleep(200);
       syn(obj1){
          sysout...
       }
    }
    死锁:互斥、循环等待
      

  2.   

    嗯 有点明白了。我现在又改了下代码:
    synchronized(tsd.sb){
    try{
    Thread.sleep(100);
    mt.join();
    System.out.println("sb"+tsd.sb);
    }catch(InterruptedException e){
    e.printStackTrace();
    }
    }
    我在mt.join()之前加了sleep(100),这个时候线程有极大概率发生死锁,对吗?假如此时cpu分配给main线程的时间片刚好在执行mt.start()结束,轮到mt执行,这个时候就不会发生死锁,对吗?这个概率极小,但是这种可能存在吗?
      

  3.   

    假设没有mt.join())?就是线程同步的问题了,和main()方法一起执行的,如果main()里面有其他方法或线程,执行的先后顺序是不确定的。
      

  4.   

    把mt.start()和mt.join()都放到main的try里
    synchronized(tsd.sb){
                try{
                mt.start(); //这样可以死锁,否则不一定,因为可能main走到syn之前mt就被执行结束了
                mt.join();
                System.out.println("sb"+tsd.sb);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }