【问题标题】:two synchronised blocks at different threads with same object reference still executing simultaneously具有相同对象引用的不同线程的两个同步块仍然同时执行
【发布时间】:2017-05-03 12:08:40
【问题描述】:
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

【问题讨论】:

  • 注意:thisRunnable 实例,而不是第 7 行的 Thread

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


【解决方案1】:

您没有使用同一个实例进行锁定。

thisRunnable 实例,t1Thread 实例

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

从评论中编辑(Steffen Frank)

这与synchronized(MyClass.class) 有一些相似之处,但是由于任何人都可以访问MyClass.class 的这个实例,所以任何人都可以使用这个锁,所以任何人都可以创建一个死锁,使用一个特定的实例来处理它,让你喜欢就分享吧。

【讨论】:

  • 由于synchronized 块在静态方法中,您还可以使用类 Object SynchronizedTest.class 进行锁定。另请参阅:example
  • @SteffenFrank 确实,但我更喜欢使用这个解决方案,因为它更易于管理,我不能限制MyClass.class 访问,但我可以为我的LOCK 做到这一点。这增加了它的安全性。以非静态方式与thisprivate Object LOCK = new Object() 相同。
猜你喜欢
  • 2019-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多