BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #45299同步于 2015/11/6
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

原子类和Sychronized的区别(锁机制)是什么?

hunanmange
2015/11/6镜像同步14 回复
RT
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
gs88pansh机器人#1 · 2015/11/6
这个我也不太了解,学习一下 通过『我邮2.0』发布
nuanyangyang机器人#2 · 2015/11/6
原子类?指的哪个?AtomicInteger吗?
hunanmange机器人#3 · 2015/11/6
【 在 nuanyangyang 的大作中提到: 】 : 原子类?指的哪个?AtomicInteger吗?嗯哪。J.U.C.atomic包下的几个类
nuanyangyang机器人#4 · 2015/11/6
【 在 hunanmange 的大作中提到: 】 : synchronized是进入的时候加锁,退出的时候解锁,总之是用锁实现的。 但是AtomicInteger之类的,是无锁的。比如addAndGet方法,对应x86的带LOCK前缀的ADD机器指令(LOCK保证那条指令专用那个内存地址,并不获取什么重量级的锁);compareAndSet方法,对应cmpxchg32指令。x86上,32位对齐了的内存读和内存写,本来就是原子的,但别的CPU并不保证,所以用AtomicInteger操作,保证在任何机器上都是原子的。volatile也保证单独的读、单独的写是原子的(注意 对volatile a来说 a++不是原子的!要原子的加,必须用AtomicInteger),但支持的操作不如AtomicInteger多。 在别的平台上,实现方法可能不一样,比如在ARM上,这种原子的读-改-写操作是先用LDREX指令读,在寄存器里改,然后用STREX写,但那个写不一定成功,如果那个地址被别的线程或当前线程用别的方法碰过了,那个写就会失败。所以,ARM上必须用一个循环:“ldrex, 改, strex, 看成功没有, 没成功就重头再试一遍”来实现。这种机制叫load-link store-conditional(LL-SC),有硬件辅助协调多个核之间的这种访问。ldrex的意思就是告诉硬件:我要互斥地访问这个地址,如果在我strex之前有人碰了这个地址,请让我的那个strex失败,我好重试一遍。
dongqing机器人#5 · 2015/11/6
原子类更底层吧
icyfox机器人#6 · 2015/11/6
写虚拟机的人好辛苦啊 还得管这个CPU那个CPU的 【 在 nuanyangyang (暖羊羊) 的大作中提到: 】 : synchronized是进入的时候加锁,退出的时候解锁,总之是用锁实现的。 : 但是AtomicInteger之类的,是无锁的。比如addAndGet方法,对应x86的带LOCK前缀的ADD机器指令(LOCK保证那条指令专用那个内存地址,并不获取什么重量级的锁);compareAndSet方法,对应cmpxchg32指令。x86上,32位对齐了的内存读和内存写,本来就是原子的,但别的CPU并不 : 在别的平台上,实现方法可能不一样,比如在ARM上,这种原子的读-改-写操作是先用LDREX指令读,在寄存器里改,然后用STREX写,但那个写不一定成功,如果那个地址被别的线程或当前线程用别的方法碰过了,那个写就会失败。所以,ARM上必须用一个循环:“ldrex, 改, strex, : ...................
nuanyangyang机器人#7 · 2015/11/6
【 在 icyfox 的大作中提到: 】 : 写虚拟机的人好辛苦啊 : 还得管这个CPU那个CPU的 : https://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html 这里有个作弊卡,有了它,c11内存模型也可以实现了。
yanboyuan机器人#8 · 2015/11/7
没有nuanyangyang理解那么深刻,不过我的理解是原子类的操作好多都是通过循环CAS实现的,并没有加锁。而Synchronized本身虽然是加锁了,不过也分偏向锁,轻量级锁,重量级锁三个级别。本来实现原子操作的方法一般来说就只有加锁和CAS两种,正好它俩各自通过不同方法实现了原子操作。
vampire24机器人#9 · 2015/11/9
synchronized是通过硬件实现的,原子类是通过软件实现的。总之,还是听暖神怎么说