Java之锁优化

为了减少锁的竞争,使线程之间更加高效的共享数据,提高性能,使用了自旋锁、自适应自旋锁、锁粗化、偏向锁等技术来进行同步优化

推荐阅读
推荐阅读

  • 自旋锁
    • 如果线程A占用共享数据的时间是短暂的,那么线程B到来时就不用挂起(这会涉及到从用户态到内核态的转换),而是让线程B先执行空循环(自旋),等到A执行完了以后B就可以使用数据了。
    • 如果物理机有多个cpu,那么就可以让另一个cpu来执行这个空循环。这意味着线程B占用了cpu却在那里闲耗着,时间一久了就是在浪费资源,所有需要有一个自旋的时间限制–自适应自旋锁
  • 自适应自旋锁
    • 自旋时间不再固定,取决于前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定
  • 锁消除
    • 在使用 synchronized 的时候,JIT会通过逃逸分析来判断这段代码没有存在线程安全问题的话,就会做锁消除
void fun() {
    Object obj = new Object();
    synchronized (obj) {
        System.out.println(obj);
    }
}
// 这段代码中的打印语句是不会有线程安全问题的
// 在编译时,JIT会优化成如下
void fun() {
    Object obj = new Object();
    System.out.println(obj);
}
  • 锁粗化
    • 大部分情况下,减小锁的粒度是很好的。但是存在特殊情况
    • 如果一段代码,反复地对一个对象进行加锁,那么是很浪费资源的做法,比如在循环体中对同一个对象加锁
    • 如果JIT发现一连续的操作都是对同一个对象反复加锁,就会进行锁粗化
int i = 0;
Object obj = new Object();
while (i++ < 100) {
    synchronized (obj){
        // do something
    }
}
// 优化为
synchronized (obj){
    while(i++ < 100){
        // do something
    }
}
  • 偏向锁
    • 在务竞争的情况下,消除对数据的同步原语

你可能感兴趣的:(Java)