今天就跟大家聊聊有关Java并发编程中并发机制的底层实现原理是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
Java中的并发机制依赖于JVM的实现和CPU指令,接下来我们深入底层探索Java并发机制的实现原理。
1、volatile
Java中允许线程访问共享变量,为了保证共享变量能够一致的被更新,线程应该确保通过排他锁单独的获取这个变量。Java中就提供了volatile,如果一个字段被声明成volatile,在java线程内存模型确保所有的线程看到的这个变量的值都是一致的。
volatile是一种轻量级synchronized,而且执行的成本比较低,没有上下文切换的消耗。volatile修饰的共享变量在进行写操作的时候,在多处理器下会引起两件事:
(1)、将当前处理器缓存行的数据写会到系统内存
(2)、这个回写操作会使得CPU中其他的处理器缓存了该地址的数据无效。
对于高速缓存行是64个字节宽的处理器,如果队列的头节点和尾节点都不足64字节的话,处理器会将他们读到同一个高速缓存行,修改头节点时,会将整个缓存行锁定,导致其它的处理器不能读到自己的高速缓存区的尾节点。影响出队列和入队列操作的效率。追加64字节能够对volatile的性能进行优化,避免头节点和尾节点同时加载到同一个高速缓存行中,避免互相锁定。
2、synchronized
上面的追加字节的方式可能在Java 7 中不生效,它会淘汰或重排序无用的字段,除了volatile,Java中用的较多的的synchronized,下面看一下:
synchronized是一种重量级锁,Java中每个对象多可以作为锁,具体是下面3种形式:
(1)、普通同步方法,锁是当前实例对象
(2)、静态同步方法,琐是当前类的Class对象
(3)、同步方法块,锁是synchronized 括号里配置的对象
synchronized用的锁是存在Java对象头的,对象头中有字段标示当前是哪种锁,锁一共4种状态、级别由低到高:无锁状态、偏向锁状态、轻量级锁、重量级锁
三种锁的对比
锁 | 优点 | 缺点 | 适用场景 |
偏向锁 | 加锁和解锁不需要额外的消耗, | 如果线程间存在锁的竞争,会带来额外的锁撤销的消耗 | 适用于只有一个线程访问同步块的场景 |
轻量级锁 | 竞争的线程不会阻塞,提高了线程的响应时间 | 如果始终得不到锁竞争的线程,会自旋消耗CPU | 追求响应时间,同步块执行非常快 |
重量级锁 | 线程竞争不会使用自旋,不会消耗CPU, | 线程阻塞,响应时间缓慢 | 追求吞吐量,同步块执行速度较慢 |
3、原子操作
原子操作是指不可中断的一个或一系列的操作,一般的处理器是利用总线加锁或者缓存加锁的方式实现多处理器之间的原子操作。
总线锁定:处理器提供一个LOCK # 信号,刚一个处理器在总线上输出一个信号时,其它的处理器请求就会被阻塞住,那么该处理器就可以独占共享内存了。
缓存锁定:内存区域如果被缓存在处理器的缓存行中,在Lock操作期间被锁定,在执行锁操作回写到内存时,处理器不在总线上声言LOCK #信号,而是修改内存地址,缓存的一致性机制会阻止同时修改由2个以上处理器缓存的内存区数据,其他的处理器成功回写被锁定的缓存行数据时,会使缓存行无效,其它的处理器就不能在使用这个缓存行了。
Java中是通过使用锁个CAS(atomic包)的方式来实现原子操作。
看完上述内容,你们对Java并发编程中并发机制的底层实现原理是什么有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注编程网行业资讯频道,感谢大家的支持。