Synchronized升级过程是怎样的

技术Synchronized升级过程是怎样的Synchronized升级过程是怎样的,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。要理解Synchron

什么是同步升级过程?针对这个问题,本文详细介绍了相应的分析和解决方法,希望能帮助更多想要解决这个问题的伙伴找到更简单易行的方法。

要理解Synchronized,首先要明确偏向锁、轻量锁和重量级锁。在使用方面,我们需要有等待/等待(时间)/通知/全部通知等。让我们介绍同步的过程和用法。

Synchronized的升级过程

(Java SE 1.6中为了减少获得锁和释放锁带来的 性能消耗而引入的偏向锁和轻量级锁)

Synchronized的升级顺序是 无锁--偏向锁--轻量级锁--重量级锁,顺内不可逆。

00-1010当一个线程访问同步代码块并获取锁时,会将锁偏置的线程ID存储在对象头和栈帧的锁记录中,偏置锁是可重入锁。未来在进入和退出同步代码块时,线程不需要CAS操作进行锁定和解锁,只需要简单的测试一下对象头的 Mark Word 里是否存储着指向当前线程的偏向锁(当前线程的线程ID).如果测试成功,则意味着线程已经获得了锁;如果测试失败,需要测试Mark Word中的偏置锁标志是否设置为1(表示当前是偏置锁);如果偏置锁标志为1,则使用 CAS 进行锁获取,和偏置锁标志不为1,则尝试使用CAS 将对象头的偏向锁指向当前线程和上述两个CAS来获取锁,如果CAS操作成功则获取到了偏向锁失败则代表出现了锁竞争,需要锁撤销操作.

00-1010部分锁使用等待竞争出现才释放锁,的机制,因此当其他线程试图争夺部分锁时,持有部分锁的线程将释放锁。部分锁的撤销需要一个等待拥有偏向锁的线程到达全局安全点(此时没有字节码被执行),它将首先暂停拥有偏向锁的线程,然后检查持有部分锁的线程是否是活动的。如果线程未激活,锁定对象的对象头将被设置为解锁状态。如果线程还活着,执行* *(判断是否需要持有锁),遍历偏向对象的锁记录,查看使用情况,如果还需要持有偏向锁,则偏向锁.带有偏置锁的Stacks会升级为轻量锁,如果不再需要偏置锁,锁对象会恢复到解锁状态,最终唤醒挂起的线程。

在00-1010线程执行同步块之前,JVM会先在当前线程的栈帧中创建一个存储锁记录的空间,并将对象头中的Mark Word复制到锁记录中,官方称之为移置Mark Word。然后线程尝试使用CAS用指向锁定记录的指针替换对象头中的标记字。如果成功,当前线程获得锁;如果失败,这意味着其他线程争夺锁,当前线程试图使用自旋来获取锁,自旋有一定次数,如果超过设置自旋的次数则升级到重量级锁或者一个线程在持有锁,一个在自旋,又有第三个来访时,轻量级锁升级为重量级锁,重量级锁使除了拥有锁的线程以外的线程都阻塞,防止CPU空转.

偏向锁

轻度解锁时,将使用原子CAS操作将移位的标记字替换回对象头。如果成功了,就意味着没有竞争发生。如果失败,表示当前锁存在竞争,锁就会膨胀成重量级锁.

* *例如:*T1线程持有锁,T2线程旋转,但是T2线程的最大旋转次数已经过了,所以旋转失败,锁升级为重量级锁。T2线程被阻塞。此时,T1已经完成了同步代码块的执行,并解锁了轻量级锁。但是此时Mark Word中的标志位已经从00(偏置锁)变为10(中级锁),所以CAS解锁时会失败,T1会。

锁撤销

Synchronized是一个不公平的锁。当一个线程进入阻塞队列时,等待的线程会先尝试获取锁,如果无法获取,就会进入阻塞队列,这对已经进入队列的线程显然是不公平的。

轻量级锁

锁定优缺点偏向锁定的场景。

>加解锁不需要过多的资源消耗,和非同步方法的相比仅仅是纳秒的差距如果存在所竞争,会有额外的锁撤销操作适用于只有一个线程访问的场景轻量级锁竞争线程不会阻塞,会自旋,减少了上线文切换。如果始终得不到锁,会消耗cpu资源追求响应时间,同步代码块多为计算,执行快的场景重量级锁没啥优点线程阻塞响应时间慢同步代码块执行时间较长的场景使用

流程图

Synchronized升级过程是怎样的

  • Synchronized 方法

    1: Synchronized 是java的内置锁,也是排它锁非公平锁排它锁也就是当前线程获取锁后,其他线程都会阻塞挂起 ,非公平锁是在线程后去锁的时候会先尝试后去锁,获取不到在进行阻塞。

    2: Synchronized 是如何保证 '原子性' 的?是因为进入 Synchronized 块的内存语义是把 Synchronized 块内使用的 '工作内存清除', 这样在使用共享变量时就会直接存主内存中获取并复制到工作你内存中,在退出 Synchronized 语句块时 会把 工作内存中计算过的 '共享变量' 更新到主内存中。

    3: 获取到 Synchronized 锁 ,都是 '对象锁'而非'代码块锁' (锁的都是对象或类,而不是某个方法),因此 Synchronized 是具有可重入性,在获取到该对象锁后可以不用再次获取该对象其他方法的锁,直接进入。

    4: 如果是 Synchronized 用在 static 上, 就代表是类锁(.class)无论创建多少个对象都不可行

    区别

    wait和sleep区别在于wait会释放锁, 但是sleep不会释放锁 ,sleep会导致线程阻塞挂起。

    wait/wait(timeout)/notify/notifyAll 方法仅可以在获取到锁后才可以使用。

    解释

    wait: 线程等待。

    wait(time): 线程等待,如果时间超过了设置的time,则继续执行。

    notify: 随机唤醒一个等待的线程。

    notifyAll: 唤醒全部等待线程。

    代码演示

    /**
     * @Auther: concurrenncy
     * @Date: 2019-03-25 16:43
     * @Company: 随行付支付有限公司
     * @maill: lan_tao@suixingpay.com
     * @Description: wait 和 sleep 区别在于 wait会释放锁, 但是 sleep 不会 ,sleep会导致线程阻塞挂起
     */
            public class WaitAndNotifyTest {
                private static Object obj = new Object();
                public static void main(String[] args) {
                    // 创建线程 thread1
                    Thread thread1 = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                System.out.println(Thread.currentThread().getName() + "   begin wait...");
                                synchronized (obj) {
                                    obj.wait();
                                }
                                System.out.println(Thread.currentThread().getName() + "   end wait...");
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }, "thread1");
                    // 创建线程 thread2
                    Thread thread2 = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                System.out.println(Thread.currentThread().getName() + "   begin wait...");
                                synchronized (obj) {
                                    obj.wait();
                                }
                                System.out.println(Thread.currentThread().getName() + "   end wait...");
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }, "thread2");
                    // 启动
                    thread1.start();
                    thread2.start();
                    try {
                        // 睡眠一秒
                        Thread.sleep(1000L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    // 如果调用 notify 的线程未获取 对象锁,在调用 notify 的时候会抛出 java.lang.IllegalMonitorStateException 异常
                    synchronized (obj) {
                        // 唤醒 使用 obj 调用 wait 方法的其中一个线程 (随机)
                        obj.notify();
                        // 唤醒 使用呢 obj 调用 wait 方法的所有线程
                        obj.notifyAll();
                    }
                }
            }
  • 关于Synchronized升级过程是怎样的问题的解答就分享到这里了,希望

    内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/38063.html

    (0)

    相关推荐

    • 自制柚子茶,家庭自制蜂蜜柚子茶要怎么做

      技术自制柚子茶,家庭自制蜂蜜柚子茶要怎么做在冬天这个时候,是吃柚子的最佳时节,柚子皮具有很好的清热去火功能,并且柚子皮在擦拭水龙头等厨具上面还可以很好的清洁污渍,所以小编的柚子皮都是充分利用的,最喜欢的就是用它来做蜂蜜柚

      生活 2021年10月28日
    • 手机分屏怎么弄,手机分屏模式怎么切换两面全屏

      技术手机分屏怎么弄,手机分屏模式怎么切换两面全屏方法/步骤分步阅读1/5
      分屏切换为全屏
      点击分屏线中间的按钮手机分屏怎么弄,向上或向下滑动,即可将想放大的界面变成全屏。
      2
      /5
      互换分屏位置
      点击分屏线中间的按钮,点

      生活 2021年10月27日
    • 环境,6)Linux文件系统二

      技术环境,6)Linux文件系统二 环境(6)Linux文件系统二一:计算机间的数据传输
      windows---linux :lrzsz :需要手动安装 yum install lrzsz -y ; rz

      礼包 2021年11月15日
    • Atomikos + druid 多数据源数据库连接超时回收问题怎么解决

      技术Atomikos + druid 多数据源数据库连接超时回收问题怎么解决Atomikos + druid 多数据源数据库连接超时回收问题怎么解决,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细

      攻略 2021年12月1日
    • 高抬腿的正确做法,胖子跑步上气不接下气怎么解决

      技术高抬腿的正确做法,胖子跑步上气不接下气怎么解决答:首先你要排除有没有心肺功能疾病高抬腿的正确做法?如果没有这方面的疾病的话,就在跑步的时候循序渐进,每天坚持跑,先跑个500米,然后加码,逐渐加上去,让你的身体逐渐适应

      生活 2021年10月25日
    • Java语言和C++语言有什么差异

      技术Java语言和C++语言有什么差异本篇内容主要讲解“Java语言和C++语言有什么差异”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java语言和C++语言有什么差异”吧

      攻略 2021年11月29日