0

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

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

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

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

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

请问还有什么其他机制?

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

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

4

4 回答 4

2

只有将两者混合在一起时才有区别。

唯一的基本规则是,在任何给定时间,同一块synchronized(foo)中只能有一个线程。就是这样。 (唯一值得一提的是,一个线程可以在多个嵌套块中。)synchronized(foo)foosynchronized(foo)foo

如果一些代码在一个synchronized(foo)块内,而一些代码在一个synchronized(bar)块内,那么这些代码可以同时运行——但你不能让两个线程synchronized(foo)同时在块内运行代码。

于 2012-07-07T18:25:02.290 回答
1

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

并不真地。例如,在“this”上同步时,如果两个线程有​​相同类的 2 个不同实例,则它们可以访问同一个块。但是,是的,例如,只有一次访问该块。并且在此上的任何同步块也只有一个访问权限

“同步”意味着只有 1 个线程可以访问同一实例上的任何同步块。因此,如果您在 2 个不同的源文件中有 2 个同步块,但在同一个实例上,如果一个线程位于其中一个块内,则另一个线程无法访问这两个同步块

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

于 2012-07-07T18:25:06.930 回答
0

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

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

--依赖对象被锁定的可用性

于 2012-07-07T18:24:25.893 回答
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
    }
  }
}

其中,如果您始终在私有成员变量上进行同步,那么您知道您是唯一使用该引用作为锁的人。

于 2012-07-09T12:43:36.043 回答