1:volatile
volatile实现的两条原则
a)volatile编译生成的lock指令会引起处理器缓存歇写回到主内存。
b)一个处理器的缓存写回到主内存会导致其他处理去的缓存失效。
2:synchronized
java中的每一个对象都可以作为锁
对于普通同步方法,锁的是当前实例对象
对于静态同步方法,锁的是当前类的class对象
对于同步方法块,锁的是synchronized括号里配置的对象
方法块的同步使用moniterenter和moniterexit实现,而同步方法使用另外一种方式实现,细节在jvm中没有详细的说明
moniterenter和moniterexit在代码编译的时候会插入到同步代码块的开始和结束位置。
3:Java对象头
synchronized用的锁是存在java对象头里面的,32位的虚拟机中,1字宽等于4字节。
如果对象是数组类型,则虚拟机使用3个字宽存储对象头
如果对象不是数组类型,则虚拟机使用2个字宽存储对象头

mark word默认存储对象的hashcode,分代年龄和锁标记,下面是mark word示意图,

4:偏向锁
a)大多数情况下,锁不仅不存在多线程竞争,而且总是由同一个线程获得,为了让线程获取锁的代价更低,引入了偏向锁。
b)偏向锁使用了一种等到竞争出现时才会释放锁的机制,当其他线程有竞争偏向锁时,偏向锁的线程才会释放锁。
c)偏向锁在java6和java7中默认是打开的,可以通过设置jvm参数-xx:UseBiasedLocking=false来关闭。
5:轻量级锁
a)线程执行同步块之前,jvm先在当前线程的栈桢中创建用于存储锁记录的空间
b)将对象头中的mark word复制到锁记录中
c)线程尝试修改对象头中的mark word替换为指向锁记录的指针,如果成功,获得锁,如果失败,就表明存在竞争,当前线程使用cas自旋来获取锁
自旋会消耗CPU,为了避免无用的自旋,锁会升级成重量级锁。
6:锁优缺点

7:处理器如何实现原子操作
a)使用总线锁,就是使用处理器提供的一个lock信号,当处理器在总线上输入此信号,其他处理器的请求将会被阻塞,那么改处理器就可以独占共享内存。
b)使用缓存锁定,内存区域如果被缓存在处理器的缓存行中,并且在lock锁定期间,缓存一致性会阻止同时修改由两个以上处理器缓存的内存数据,其他的处理器回写已被锁定的缓存行数据时,会使缓存行无效。
两种情况不会使用缓存锁定
a:操作的数据不能缓存在处理器内部,或操作的数据跨多个缓存行时,会使用总线锁定
b:处理器不支持缓存锁定
如果你觉得每天一记有用,或者想获取更多内容,请扫下面二维码~~~

扫一扫 关注我的公众号
如果你想要跟大家分享你的文章,欢迎留言投稿~
如果你喜欢,请留下你的赞哦