虚拟机锁优化

  • 锁偏向

  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高并发程序设计》

原文地址:https://www.cnblogs.com/simple-ly/p/11123650.html

时间: 2024-08-05 12:10:25

虚拟机锁优化的相关文章

Java虚拟机对锁优化所做的努力(读书笔记)

锁偏向 是一种加锁操作的优化手段,他的核心思想是:如果一个线程获得了锁,那么就进入偏向模式,当这个线程再次请求锁时,无须在做任何同步操作,因此在几乎没有锁竞争的场合,偏向锁是比较好的优化效果,因为连续多次极有可能是同一个线程请求同一个相同的锁,对于锁竞争比较激烈的场合,其效果不佳,因为竞争激烈的场合,最有可能的情况是每次都是不同的线程来请求相同的锁,这样偏向模式就会失效,使用Java虚拟机参数-XX:+UseBiasedLocking可以开启偏向锁, 轻量级锁 如果偏向锁失败,虚拟机并不会立即挂

虚拟机中的锁优化简介(适应性自旋/锁粗化/锁削除/轻量级锁/偏向锁)

高效并发是JDK 1.6的一个重要主题,HotSpot虚拟机开发团队在这个版本上花费了大量的精力去实现各种锁优化技术,如适应性自旋(Adaptive Spinning).锁削除(Lock Elimination).锁膨胀(Lock Coarsening).轻量级锁(Lightweight Locking).偏向锁(Biased Locking)等,这些技术都是为了在线程之间更高效地共享数据,以及解决竞争问题,从而提高程序的执行效率. 13.3.1 自旋锁与自适应自旋 前面我们讨论互斥同步的时候,

Java虚拟机--线程安全和锁优化

Java虚拟机--线程安全和锁优化 线程安全 线程安全:当多线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那么这个对象就是线程安全的. Java中,线程安全体现在多个线程访问同一个共享数据,如果一段代码中根本不会与其他线程共享数据,可以说不存在线程安全的问题. 线程安全的安全程度,由强至弱排序,可以分为以下5类. 不可变 不可变的对象一定是线程安全的,final关键字可以实现

Java 虚拟机对锁优化所做的努力

作为一款公用平台,JDK 本身也为并发程序的性能绞尽脑汁,在 JDK 内部也想尽一切办法提供并发时的系统吞吐量.这里,我将向大家简单介绍几种 JDK 内部的 "锁" 优化策略. 1. 锁偏向 锁偏向是一种针对加锁操作的优化手段. 如果一个线程获得了锁,那么锁就进入偏向模式.当这个线程再次请求锁时,无须再做任何同步操作.这样就节省了大量有关锁申请的操作,从而提高了程序性能. 因此,对于几乎没有锁竞争的场合,偏向锁有比较红啊的优化效果,因为连续多次极有可能是同一个线程请求相同的锁.而对于锁

深入理解Java虚拟机(第三版)-14. 线程安全与锁优化

14. 线程安全与锁优化 1. 什么是线程安全? 当多个线程同时访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替进行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那就称这个对象是线程安全的 2. Java语言中的线程安全 我们将Java语言下的线程安全分为以下五类:不可变.绝对线程安全.相对线程安全.线程兼容和线程对立. 1.不可变:不可变一定是线程安全的,无论是对象的方法实现还是方法的调用者,都不需要进行任何线程安全保障措施

深入理解java虚拟机-第13章-线程安全与锁优化

第十三章 线程安全与锁优化 线程安全 java语言中的线程安全 1 不可变.Immutable 的对象一定是线程安全的 2 绝对线程安全 一个类要达到不管运行时环境如何,调用者都不需要额外的同步措施,通常需要付出很大甚至是不切实际的代价,在java api中标注自己是线程安全的类,大多数都不是绝对的线程安全 3 相对线程安全 4 线程兼容  对象本身不是线程安全的,但是可以通过在调用端正确地使用同步手段来保证对象在并发环境中可以安全使用 5 线程对立 线程安全的实现方法 1 互斥同步 Murua

jvm(13)-线程安全与锁优化(转)

0.1)本文部分文字转自“深入理解jvm”, 旨在学习 线程安全与锁优化 的基础知识: 0.2)本文知识对于理解 java并发编程非常有用,个人觉得,所以我总结的很详细: [1]概述 [2]线程安全 1)线程安全定义:当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那这个对象是线程安全的:(干货——线程安全定义) [2.1]java 语言中的线程安全(干货——java

锁机制及锁优化

   锁      在Java中目前有两种锁机制防止代码块受到并发访问的干扰:.java语言提供了一个synchronized (内部锁)或Lock/Condition(显示锁) 关键达到这一目的,在java SE 5.0引入了Lock/ReentranLock(重入锁)类. 锁具有以下作用: (1)锁用来保护代码片段,任何时刻只能有一个线程执行被保护的代码. (2)锁可以哦管理视图进入被保护代码段的线程 (3)锁可以拥有一个或多个相关条件对象 (4)每个条件对象管理哪些已经进入被保护的代码片段

JVM-并发-线程安全与锁优化

线程安全与锁优化 1.线程安全 (1)当多个线程访问一个对象时,如果不考虑这些线程在执行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那么这个对象时是线程安全的. (2)Java语言中的线程安全 a)可以将Java语言中各种操作共享的数据分为5类:不可变,绝对线程安全,相对线程安全,线程兼容和线程对立 b) 在Java语言中不可变的对象一定是线程安全的,无论是对象的方法实现还是方的调用者,都不需要再采用任何的线程安全