同步变体

时间:2013-09-19 07:57:45

标签: java synchronization

两个同步之间有什么区别:

public synchronized void set (int i) { 
   this.i = i;
}

public void set (int i) {
       synchronized (this) {
               this.i = i;
         }
    }

5 个答案:

答案 0 :(得分:2)

第一个是同步方法,第二个是同步块。

这里你在块中对这个对象synchronized都代表相同。在synchronized-method线程中获取当前对象的锁定。

注意:在synchronized块中你可以同步代码块而不是整个方法体,也可以使用不同的资源进行锁定(除此之外)。

答案 1 :(得分:1)

  • 第一种情况:整个方法已同步
  • 第二种情况:仅编写synchronized(this)的同步代码块

所以如果你把第二种方法写成

public void set (int i) {
       // Code here is not synchronized
       synchronized (this) { // only this block of code is synchronized
               this.i = i;
         }
       // code after this is also not synchronized. 
    }

但是在第二个块的情况下,您还可以同步其他一些对象。

public void set (int i) {
       synchronized (someObject) {
               this.i = i;
         }
    }

答案 2 :(得分:1)

他们是写同一件事的不同方式。 Java可能只有第二种形式。在方法的this对象上同步方法的整个主体是一种特别常见的情况,因此语言提供了一种快速,简单的方法。

Java语言规范在8.4.3.6 synchronized Methods中说明了等价。 synchronized void bump() { count++; }

具有完全相同的效果
void bump() {
    synchronized (this) {
        count++;
    }
}

答案 3 :(得分:1)

这两种同步方法是等效的,因为您在this中提供了synchronized block

同步基于内部锁定监视器锁定,每个对象的属性

正如其他答案所述,你的第一个命题是synchronized method,这意味着线程将获得当前对象的锁定。

来自Oracle教程:

  

当线程调用synchronized method时,它会自动获取该方法对象的内部锁,并在方法返回时释放它。即使返回是由未捕获的异常引起的,也会发生锁定释放。

你的第二个命题是synchronized blocksynchronized statement。在这种情况下,线程获取放入参数的对象的锁。

再次来自Oracle教程:

  

与synchronized方法不同,synchronized语句必须指定提供内部锁的对象:

在你的情况下你放了this所以它将锁定当前对象,就像同步方法那样。

但你也可以给它另一个对象,它将锁定当前对象锁定“未更改”

答案 4 :(得分:0)

两个同步之间没有区别,但第二个同步更灵活:您可以在同一方法的synchronized块之外添加未同步的代码,或者在不同于this的对象上同步