输入同步块是原子的吗? [英] Is entering synchronized block atomic?

查看:86
本文介绍了输入同步块是原子的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您知道是否可以确保Java中的同步块是原子的吗?

Do you know if there is guaranteed that synchronized block in java is atomic?

想象以下情况

线程1,2:

synchronized(object){object.modify();}

(对象是共享变量.)

想象thread_M将更改对类似对象的引用

imagine thread_M will change reference to object like

synchronized(object){object = new Object()}

现在想象线程1和2正在争夺对对象的锁定

now imagine threads 1 and 2 are competing over getting the lock on object

是否可能发生以下情况:
1.线程1:读取旧对象
2. ThreadM:修改对象引用&释放旧对象锁
3.线程2:读取新对象;检查锁;锁上它
4.线程1:检查锁(确定已读取cos旧对象);锁上它
现在两个线程都有一个锁并修改了相同的(新)对象

Is it possible that following would happened:
1. Thread1: read old object
2. ThreadM: modify object reference & release old object lock
3. Thread2: read new object; check lock; lock on it
4. Thread1: check lock (ok cos old object was read); lock on it
now both threads have a lock and modify same (new) object

所以要说明我的问题-是否可以保证在synced(对象)步骤中(步骤1和4)是原子的(如步骤3中所示)?

So to specify my question - is somewhere guaranteed that in synchronized(object) steps (1 and 4) are atomic (like depicted in step 3)?

推荐答案

object上进行同步时,您可以重新分配object,但是我无法想到重新分配的情况一个用于锁定的字段是个好主意.

You can reassign object while you are synchronized on object, but I can't think of a scenario where reassigning a field used for locking is a good idea.

在线程M退出其同步块之前,没有其他线程能够获取对object的旧值的锁定,但是只要对其他对象可见,另一个线程就可以获取对新对象的锁定.该线程.

No other thread will be able to acquire the lock on the old value of object until thread M exits its synchronized block, but another thread will be able to acquire a lock on the new object as soon as it is visible to that thread.

保证在释放锁之前线程进行的修改对于之后获取锁的线程是可见的.但是,由于您是在重新分配锁本身,因此获取线程可能看不到它已被更改,而是获取了旧值的锁.然后他们仍然看不到object已被重新分配.

Modifications made by a thread before releasing a lock are guaranteed to be visible to threads that acquire the lock afterwards. But since you are reassigning the lock itself, the acquiring thread may not see that it has been changed, and acquire a lock on the old value. Then they would still not see that object has been reassigned.

object声明为volatile变量将确保将其当前"值用于锁定.但这不会阻止两个线程同时修改同一实例:

Declaring object as a volatile variable would ensure that its "current" value is used for locking. But it wouldn't prevent two threads from modifying the same instance concurrently:

  1. 线程M获取旧值的锁.线程1读取旧值.
  2. 线程M更改值.
  3. 线程M释放对旧值的锁定.线程2读取新值.
  4. 线程1获取旧值的锁.线程2获得对新值的锁定.
  5. 线程1读取新值.线程2读取新值.
  6. 线程1修改新值.线程2修改了新值.

要避免所有这些情况,只需创建一个单独的对象进行锁定,就不要更改它.

To avoid all of this, just create a separate object for locking, and never change it.

这篇关于输入同步块是原子的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆