Java中的并发机制依赖于JVM的实现和CPU指令,接下来咱们深刻底层探索Java并发机制的实现原理。java
Java中容许线程访问共享变量,为了保证共享变量可以一致的被更新,线程应该确保经过排他锁单独的获取这个变量。Java中就提供了volatile,若是一个字段被声明成volatile,在java线程内存模型确保全部的线程看到的这个变量的值都是一致的。缓存
volatile是一种轻量级synchronized,并且执行的成本比较低,没有上下文切换的消耗。volatile修饰的共享变量在进行写操做的时候,在多处理器下会引发两件事:并发
(1)、将当前处理器缓存行的数据写会到系统内存性能
(2)、这个回写操做会使得CPU中其余的处理器缓存了该地址的数据无效。优化
对于高速缓存行是64个字节宽的处理器,若是队列的头节点和尾节点都不足64字节的话,处理器会将他们读到同一个高速缓存行,修改头节点时,会将整个缓存行锁定,致使其它的处理器不能读到本身的高速缓存区的尾节点。影响出队列和入队列操做的效率。追加64字节可以对volatile的性能进行优化,避免头节点和尾节点同时加载到同一个高速缓存行中,避免互相锁定。atom
上面的追加字节的方式可能在Java 7 中不生效,它会淘汰或重排序无用的字段,除了volatile,Java中用的较多的的synchronized,下面看一下:spa
synchronized是一种重量级锁,Java中每一个对象多能够做为锁,具体是下面3种形式:
(1)、普通同步方法,锁是当前实例对象.net
(2)、静态同步方法,琐是当前类的Class对象线程
(3)、同步方法块,锁是synchronized 括号里配置的对象对象
synchronized用的锁是存在Java对象头的,对象头中有字段标示当前是哪一种锁,锁一共4种状态、级别由低到高:无锁状态、偏向锁状态、轻量级锁、重量级锁
三种锁的对比
锁 | 优势 | 缺点 | 适用场景 |
偏向锁 | 加锁和解锁不须要额外的消耗, | 若是线程间存在锁的竞争,会带来额外的锁撤销的消耗 | 适用于只有一个线程访问同步块的场景 |
轻量级锁 | 竞争的线程不会阻塞,提升了线程的响应时间 | 若是始终得不到锁竞争的线程,会自旋消耗CPU | 追求响应时间,同步块执行很是快 |
重量级锁 | 线程竞争不会使用自旋,不会消耗CPU, | 线程阻塞,响应时间缓慢 | 追求吞吐量,同步块执行速度较慢 |
原子操做是指不可中断的一个或一系列的操做,通常的处理器是利用总线加锁或者缓存加锁的方式实现多处理器之间的原子操做。
总线锁定:处理器提供一个LOCK # 信号,刚一个处理器在总线上输出一个信号时,其它的处理器请求就会被阻塞住,那么该处理器就能够独占共享内存了。
缓存锁定:内存区域若是被缓存在处理器的缓存行中,在Lock操做期间被锁定,在执行锁操做回写到内存时,处理器不在总线上声言LOCK #信号,而是修改内存地址,缓存的一致性机制会阻止同时修改由2个以上处理器缓存的内存区数据,其余的处理器成功回写被锁定的缓存行数据时,会使缓存行无效,其它的处理器就不能在使用这个缓存行了。
Java中是经过使用锁个CAS(atomic包)的方式来实现原子操做。
参考:http://blog.csdn.net/wusd1256/article/details/78165536