十二、JVM(HotSpot)线程安全与锁优化----终结篇

注:本博文主要是基于JDK1.7会适当加入1.8内容。

线程安全:当多个线程访问一个对象时,如果不用考虑这些线程在运行环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为可以获取正确的结果,那这个对象就是线程安全的。

1、Java语言中线程安全

  • 不可变(final关键字)
  • 绝对线程安全(Vector、HashTable非绝对线程安全,集合里面还包裹着对象)
  • 相对线程安全(JDK标注为线程安全的一些类Vector、HashTable等)
  • 相对线程安全(通过一些同步方法保证线程安全,如HashMap、ArrayList等)
  • 线程对立(无论调用方是否采用了同步措施,都无法再多线程环境中并发使用,Thread类中suspend和resume方法,已被弃用)

2、线程安全实现方法

  • 互斥同步(synchronized和ReentrantLock)—-悲观
    同步是指多个线程并发访问共享数据时,保证共享数据在同一个时刻只能被一个线程使用,而互斥是实现同步的一个手段。临界区(Critical Section)、互斥量(Mutex)和共享量(Semaphore)都是主要互斥实现方式。互斥是因,同步是果;互斥是方法,同步是目的。
    -非阻塞同步(CAS可能产生ABA问题和Version)—-乐观
    -无同步方案:可重入代码和线程本地存储(ThreadLocal)

3、锁优化

(1)自旋锁和自适应自旋

线程互斥同步时,挂起和恢复线程的操作都需要转入内核态完成,并发性能压力大。如果共享数据的锁定状态很短,为了这段时间去挂起和恢复显然不值得,物理机器有一个以上的CPU能让两个或以上线程同时并发执行,我们可以让另一个线程稍微等一等,但不放弃CPU处理时间,为了线程等待,我们只需要让线程执行一个忙循环(自旋),这项技术就是自旋,默认自旋次数为10。

自适应自旋是JDK1.6引入,由起那一次在同一个锁上的自选时间及锁拥有者决定

(2)锁消除

虚拟机即时编译器运行时,对一些代码要求同步,但是被检测到不可能存在共享数据晶振的锁进行消除。

(3)锁粗化

(4)轻量级锁

对于绝大部分的锁,整个同步周期内都不存在竞争的。如果没有竞争,轻量级锁使用CAS操作避免了使用互斥量的开销,如果存在锁竞争,除了互斥量的锁竞争开销外,还额外发生CAS操作。

(5)偏向锁-XX:+UseBiasedLocking

可以提升带有同步但无竞争的程序性能,如果程序中大多数锁总是被多个不同的线程访问,那偏向锁模式是多余。

猜你喜欢

转载自blog.csdn.net/zhangwei408089826/article/details/81874347
今日推荐