synchronized(obj){...}中的`obj`参数的目的是什么?

时间:2018-08-19 05:20:35

标签: java multithreading concurrency thread-safety

这两者之间有什么区别?

public void someMethod(){

   Object lock = new Object();
   synchronized(lock){
   //some code

    }

 document.onmouseup = () => {
   console.log(window.getSelection().toString());
 };

}

也请让我说清楚,如果我在“同步括号”中提到一个对象,那意味着我将能够对该特定对象使用线程安全的吗?

2 个答案:

答案 0 :(得分:3)

使用synced关键字时,需要一个对象作为监视器锁定。只有使用相同监视器锁定的线程才会被同步。

  • synchronized(this)在当前实例上同步。在Java中检查this关键字。

    • 从不同的线程在同一实例上调用someMethod时,这些线程将被同步。
    • 在来自不同线程的不同实例上调用someMethod时,这些线程将不会同步。
  • 第二个版本没有任何同步功能,因为每个线程都有自己的方法堆栈,并且它们将在自己的方法堆栈上创建自己的Object lock

答案 1 :(得分:1)

在深入探讨差异之前,让我们首先尝试了解什么是Java中的this关键字。类的实例可以使用this引用自己。一个人也可以使用this关键字来访问类成员(仅非静态成员)。

现在,JAVA中的同步基于Objects,其中每个Object维护一个监视器,该监视器仅允许一个线程访问synchronized代码块(或synchronized方法)。因此,在不同线程之间共享相同对象很重要,这样它们才能正确同步。

上面的第一个版本可确保在多个线程之间共享该类的相同实例时进行正确的同步。

第二个版本基本上是每次调用new Object时都会创建一个someMethod,这意味着即使在多个线程之间共享了该类的相同实例,每个线程也会在上进行同步lock对象的“>不同副本,从而有效地导致没有同步。

为了使事情更清楚一点,这里是第一版的其他一些变种。

public void someMethod() {
 // Note that assignment below is redundant and is shown for example purposes.
 Object lock = this;
 synchronized(lock){
    //some code
  }
}

public synchronized void someMethod() {
 //some code
}

应选择哪个版本。这完全取决于采取什么方法。

如果通过方法执行的所有操作都需要同步,那么我更喜欢使用synchronized方法(最后一个选择)。这样可以防止额外的缩进,并且可读性更高。否则,第一个变体有意义,您可以在其中执行不需要在synchronized块外进行同步的操作。