在同一对象引用的不同线程上的两个同步块仍然同时执行

时间:2017-05-03 12:08:40

标签: java multithreading synchronization java-threads synchronized-block

public class SynchronizedTest
{
  public static void main(String argv[])
  { 
     Thread t1 = new Thread(new Runnable(){public void run()
     {
        synchronized (this)    //line 7
        {
            for(int i=0; i<100; i++)
                System.out.println("thread A "+i);
        }

    }});
    t1.start();
    synchronized(t1)       // line 15
    {
        for(int i=0; i<100; i++)
            System.out.println("thread B "+i);
    }
  }     
} 

如果我理解正确,那么在第7行同步块引用对象t1和第15行同步块也引用相同的对象,以便一次只有一个线程可以获取此对象的锁和其他人必须等待。

然后为什么他们互相争斗?输出混合如

   thread B 62
   thread B 63 
   thread B 64
   thread A 0
   thread A 1
   thread A 2
   thread B 65
   thread A 3

1 个答案:

答案 0 :(得分:2)

您没有使用相同的实例进行锁定。

thisRunnable个实例,t1Thread个实例

我更喜欢声明private static Object LOCK = new Object();,这是内存中最小的实例,这很容易知道它的用途。

从评论中编辑(由Steffen Frank撰写)

这与synchronized(MyClass.class)有一些相似之处,但由于任何人都可以访问MyClass.class的这个实例,任何人都可以使用此锁,因此任何人都可以创建死锁,使用特定的实例可以帮助您,如果你愿意,让你分享。