同步变体 [重复]

Posted

技术标签:

【中文标题】同步变体 [重复]【英文标题】:Synchronization variants [duplicate] 【发布时间】:2013-09-24 05:04:18 【问题描述】:

这两种同步有什么区别:

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

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

【问题讨论】:

另见:***.com/questions/4394976/… 【参考方案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;
         
    

【讨论】:

但它是一样的,不是吗? @ceving,你的例子在功能上是一样的。但是如果你想要一个应该完全同步但只有一个代码块的方法,那么你将不得不使用第二种方法 我可以为这个代码块写一个额外的方法。 @ceving,是的,你可以,但是如果你写一个单独的方法并同步它,你不能在答案中提到的其他对象上同步。【参考方案2】:

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

在这里,您 synchronized 在块中的此对象上都表示相同。在synchronized-method线程中获取当前对象的锁。

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

【讨论】:

【参考方案3】:

这两种同步没有区别,但第二种更灵活:可以在synchronized块之外以相同的方法添加不同步的代码,或者在与this不同的对象上同步。

【讨论】:

【参考方案4】:

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

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

效果完全一样
void bump() 
    synchronized (this) 
        count++;
    

【讨论】:

【参考方案5】:

这两种同步方式是等价的,因为你在synchronized block中给了this

同步是基于Intrinsic LockMonitor Lock,每个Object的一个属性

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

来自 Oracle 教程:

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

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

再次来自 Oracle 教程:

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

在您的情况下,您输入了this,因此它将像同步方法一样获取当前对象的锁。

但你也可以给它另一个对象,它会占用它的锁,而当前对象锁“不变”

【讨论】:

以上是关于同步变体 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

线程同步之条件变量使用手记

非同步线程和同步线程的区别[重复]

如何同步hasMany关系上的子表数据?

同步关键字不使函数同步:Java [重复]

Effective java 第十章 并发 避免过度同步 读书笔记

kettle定时每天同步数据如何避免重复