synchronized(this)和synchronized(objectReference)之间的差异

时间:2012-07-07 18:15:32

标签: java synchronized

我想更好地理解线程进入synchronized(this)块vs synchronized(someObjectReference)块时实际发生的机制。

    synchronized (this) {
        // Statement 1
        // Statement 2
    }

    synchronized (someObjectReference) {
        // Statement 1
        // Statement 2
    }

据我理解:(我错过了什么?我错了吗?)

  • 在这两种情况下,一次只有1个线程可以访问同步块
  • 当我们在someObjectReference上进行同步时:
    • 一次只有一个线程可以在此块中访问/修改
    • 一次只能有一个帖子进入此区块

还有哪些其他技工?

    synchronized (objectReference) {
        // Statement 1 dealing with someObjectReference
        // Statement 2 not dealing with someObjectReference
    }

在上面的示例中,将不处理mutex的语句添加到synchronized块中是否有意义?

4 个答案:

答案 0 :(得分:1)

将两者混合在一起时只会有所不同。

synchronized(foo)的单一基本规则是,在任何给定时间,只有一个线程可以位于同一synchronized(foo)的{​​{1}}块中。那是它。(唯一值得一提的警告是,一个线程可以位于同一foo的几个嵌套synchronized(foo)块内。)

如果某些代码在foo块内,并且某些代码在synchronized(foo)块内,那么这些代码片段可以同时运行 - 但是你不能让两个代码运行代码synchronized(bar)同时阻止。

答案 1 :(得分:0)

同步基本上意味着程序请求对指定对象进行锁定...如果一个线程无法进入任何同步块,那么这意味着任何其他线程已经锁定了指定的对象。代码的指定如果成功获取锁,则该区域内的线程可以进入..

 In both cases, only 1 thread can access synchronized block at a time

- 取决于要锁定的可用对象

答案 2 :(得分:0)

  

在这两种情况下,一次只有1个线程可以访问同步块

不是真的。例如,当同步“this”时,如果2个线程有2个不同的同一类实例,则它们可以访问同一个块。但是,是的,对于一个实例,只有一个访问块。此

上的任何同步块也只有一个访问权限

“已同步”表示只有一个线程可以访问同一实例上的任何同步块。因此,如果您在2个不同的源文件中有2个同步块,但在同一个实例上,如果其中一个块中有一个线程,则另一个线程无法访问两个同步块

关于“在同步块中做什么”:只做处理同步对象的事情。任何其他不需要同步的指令都会锁定资源,这可能会造成瓶颈

答案 3 :(得分:0)

关于this同步的一个重要注意事项是处理可见性问题。假设您有一个班级A,它会在this上同步。使用A的任何代码都引用了用于锁定的对象A。这意味着A的用户如果也锁定A实例,则可能会创建死锁。

public class A implements Runnable {
  public void run() {
    synchronized (this) {
      // something that blocks waiting for a signal
    }
    //other code
  }
}

public class DeadLock {
  public void deadLock() {
    A a = new A();
    Thread t = new Thread(a);
    t.start();

    Thread.sleep(5000); //make sure other thread starts and enters synchronized block
    synchronized (a) {
      // THIS CODE BLOCK NEVER EXECUTES
      // signal a
    }
  }
}

如果你总是在私有成员变量上同步,你知道你是唯一一个使用该引用作为锁的人。