虚拟机锁优化
Posted simple-ly
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了虚拟机锁优化相关的知识,希望对你有一定的参考价值。
-
锁偏向
synchronized默认采取非公平锁,锁偏向是指线程在释放锁后再次进入请求队列中等待获取锁时,虚拟机会优先唤醒该线程。并省去获取锁的操作,进行无锁操作。
代码:
public class BIasLockTest public static void main(String[] args) Object lock = new Object(); AtomicInteger num = new AtomicInteger(); for(int i = 0; i < 100; i++) Thread t = new ThreadA("t" + i,lock,num); t.start(); class ThreadA extends Thread private Object lock; private AtomicInteger num; public ThreadA(String name, Object lock,AtomicInteger num) super(name); this.lock = lock; this.num = num; @Override public void run() while(num.getAndIncrement() < 100) synchronized (lock) System.out.print(Thread.currentThread().getName() + " ");
输出片段:
t0 t0 t0 t0 t0 t0 t0 t0 t0 t0 t0 t0 t0 t0 t0 t4 t4 t4 t4 t4 t4 t4 t4 t4 t4 t3 t3 t3 t3 t3 t3 t3 t3 t3 t3 t3 t3
t3 t3 t4 t4 t4 t4 t0 t55 t2 t44 t1 t8 t7 t3
-
轻量级锁
当锁竞争比较激烈,偏向锁就会失效,例如这一段:t4 t4 t4 t0 t55 t2 t44 t1 t8 t7 t3
基本上每次获取锁的线程都不一样,偏向锁失效后,会升级为轻量级锁。
轻量级锁将对象头部作为指针指向持有锁的线程堆栈的内部,来判断一个线程是否持有对象锁。
线程获取轻量级锁成功后可以进入临界区。获取失败则膨胀为重量级锁。
-
自旋锁
轻量级锁膨胀为重量级锁后,为了避免线程真实的在操作系统层面挂起,虚拟机让线程执行几个空循环,目的是等待其他线程释放锁资源。
空循环以后,如果获取锁成功,则自旋成功,如果依旧获取失败,则线程在操作系统层面挂起,等待被唤醒。
-
锁消除
锁消除涉及逃逸分析,逃逸分析是观察某一个变量是否会逃出某一个作用域。
例如在方法中存在一个Vector类型的临时变量,这个临时变量只在这个方法中使用,那个对这个临时变量的任何操作都只会在当前线程进行。这类无意义的加锁完全可以去掉。
参考:
《实战Java高并发程序设计》
以上是关于虚拟机锁优化的主要内容,如果未能解决你的问题,请参考以下文章