• synchronized原理


    目录

    一、基本特点

    二、优化操作

    1、锁升级

    2、锁消除

    3、锁粗化


    一、基本特点

    从锁策略的角度,可以分析出synchronized具有以下特点:

    (1) 开始是乐观锁,锁冲突激烈转化为悲观锁;

    (2) 开始是轻量级锁,如果锁被持有的时间较长,就转换为重量级锁;

    (3) 轻量级锁的部分是基于自旋锁实现的,重量级锁的部分是基于挂起等待锁实现的;

    (4) 不是读写锁,是普通互斥锁;

    (5) 是非公平锁;

    (6) 是可重入锁。

    二、优化操作

    1、锁升级

    JVM将synchronized分为无锁、偏向锁、轻量级锁、重量级锁几种状态,根据不同情况,状态会进行升级。

    无锁,即不加锁的状态。

    偏向锁:

    偏向锁类似于单例模式中的“懒汉模式”,必要的时候才会真正加锁

    偏向锁会给锁对象设置一个标志位,记录这个锁属于哪个线程:

    如果后续没有其他线程来竞争这个锁,那么就不需要真加锁;

    如果后续有其他线程来竞争这个锁,那么就取消偏向锁的状态,进入轻量级锁的状态。

    举个栗子:两个线程同时进行count++操作

    1. public class Test {
    2. private static int count;//计数器
    3. private static Object locker = new Object();//锁对象
    4. //自增方法
    5. public static void getAndIncrement(){
    6. synchronized (locker){
    7. count++;
    8. }
    9. }
    10. public static void main(String[] args) throws InterruptedException {
    11. Thread t1 = new Thread(() -> {
    12. for (int i = 0; i < 50000; i++) {
    13. getAndIncrement();
    14. }
    15. });
    16. Thread t2 = new Thread(() -> {
    17. for (int i = 0; i < 50000; i++) {
    18. getAndIncrement();
    19. }
    20. });
    21. t1.start();
    22. t2.start();
    23. t1.join();
    24. t2.join();
    25. System.out.println("count = "+count);
    26. }
    27. }

    如果两个线程在调度的时候恰好错开了,就不会真加锁,如下图: 

    如果两个线程在调度的时候没有完全错开,只有当t2执行到lock时,t1的lock才真正生效:

    轻量级锁:

    当线程之间产生锁竞争时,就会升级到轻量级锁状态。

    重量级锁:

    当线程之间锁竞争激烈时,就会升级到重量级锁状态。

    2、锁消除

    JVM会对我们写的代码进行判定,如果发现某段代码不必加锁,但又使用了synchronized的时候,就会直接消除这个锁。

    比如说,在单线程环境执行某一段加锁的代码时,就没必要加锁~

    或者多个线程各自获取不同的锁对象时,也没必要加锁~

    3、锁粗化

    锁粗化,就是把细粒度的锁变为粗粒度的锁。

    synchronized代码块中包含的代码少,则粒度细;包含的代码多,则粒度粗。

    如果发现代码中频繁地进行无意义的加锁操作,就会进行锁粗化~

    当然,粗化的前提是保证代码的逻辑在粗化前后是不变的~

    举个栗子:给领导打电话汇报工作时:

    方式一:

    打电话,汇报工作1,挂电话;

    打电话,汇报工作2,挂电话;

    打电话,汇报工作3,挂电话。

    方式二:

    打电话,汇报工作1,汇报工作2,汇报工作3,挂电话。

    显然,方式二更加高效~

    synchronized背后竟然做了这么多的优化~

    设计JVM的大佬,为了简化synchronized的使用,真是为我这种菜鸡操碎了心555~

  • 相关阅读:
    软著申请注意事项
    MySQL简单查询
    华为S5700交换机初始化和配置telnet,ssh用户方法
    BSN长话短说之十一:为什么NFT会成为文化数字化的核心
    Python进阶(二)-图形界面编程Tkinter(2)
    JAVA基础小结(项目三)
    Remote Desktop Service (RDS) 远程桌面服务漏洞简介 BlueKeep DejaBlue
    Spring Cloud Gateway 网关实现白名单功能
    .NET6发布项目到腾讯云Windows2012R全网最详细教程
    【网络编程】传输层——TCP协议
  • 原文地址:https://blog.csdn.net/m0_67683346/article/details/127131646