关于synchronized:Java6对synchronized的优化锁升级过程详细过程

前言以前咱们在温习synchronized的时候,和lock一比照,总说它是一个重量级锁,性能很差,不如lock来的不便,但其实synchronized作为Java中元老级的关键字,很多jdk原始代码都有用到它,因而Java开发团队还是十分中意这个“私生子”的,所以为了给它减重,开发者也早在Java6就为synchronized专门设计了一套优化处理过程。 一、synchronized应用加到办法上,锁就是这个对象,避免多个线程同时拜访这个对象的synchronized办法;加到静态方法,锁就是这个类的class对象,避免多个线程同时拜访这个类的synchronized办法,对该类所有对象实用;加到代码块,锁就是该代码块所在的对象,避免多个线程同时拜访该代码块;二、JVM对synchronized的实现形式代码块同步:通过应用 monitorenter 和 monitorexit 指令实现的同步办法:ACC_SYNCHRONIZED 润饰三、Java对象头(存储锁类型)理解锁降级之前,必须先晓得Java对象头,正式对象头记录的信息才实现了锁降级过程中的线程判断。 Java对象: Java对象头:蕴含两局部:MarkWord 和 类型指针 MarkWord:Mark Word 用于存储对象本身的运行时数据,如 HashCode、GC分代年龄、锁状态标记、线程持有的锁、偏差线程ID等等。 占用内存大小与虚拟机位长统一(32位JVM -> MarkWord是32位,64位JVM -> MarkWord是64位) 四、锁降级过程无锁状态 -> 偏差锁 -> 轻量级锁(自旋锁,自适应自旋) -> 重量级锁 各种锁状态下mark word的内容:状态偏差锁位标记位存储内容未锁定001对象哈希码、对象分代年龄偏差锁101偏差线程ID、偏差工夫戳、对象分代年龄轻量级锁定000指向锁记录的指针收缩(重量级锁定)010执行重量级锁定的指针GC标记011空(不须要记录信息)无锁状态 -> 偏差锁首先当处于无锁状态时,MarkWord中存储的是对象的hash code等信息,偏差锁为0,此时线程1进入,发现没有记录线程ID信息,则间接CAS操作将本人的线程ID设置进去,设置胜利则获取到偏差锁,偏差锁标记为改为1;失败则要降级为轻量级锁; 线程1执行完后,将markWord中的线程ID设置为空,即开释偏差锁; 如果在线程1开释之前,此时线程2进入,先查markWord中记录的线程ID是否是本人的(这也是偏差锁实用的场景:教训表明,大多数状况下,都是同一个线程进入同一个同步代码块),若是,则获取锁胜利; 不是,则阐明曾经偏差给了其余线程,即呈现了线程竞争的状况,此时个别状况下,偏差锁是不能够重偏差的,所以须要降级,如果是能够重偏差的,则会尝试CAS操作替换markWord中的线程id,胜利则偏差给线程2,失败则进行锁降级; 偏差锁在降级前,须要先将偏差锁撤销。 如果此时曾经偏差给了某个线程,则须要依据markWord中记录的线程id查问该线程是否存活,不存活,则进入无锁状态,或者可重偏差状态,存活则撤销偏差锁,将锁对象的markWord复制到线程栈中,开始降级 偏差锁 -> 轻量级锁呈现两个及以上线程竞争时(曾经偏差给了一个线程,此时又呈现了另外一个线程竞争,即降级),开始降级为轻量级锁。 加锁时,线程会在本人的栈帧中创立一个Lock Record锁记录(会将对象原来的markWord内容复制过去,作为一个lockRecord,蕴含对象分代年龄等信息,而原来的markWord只会有一个指针),同时CAS将锁对象的markWord中替换为指向该lockRrecord的指针,操作胜利则获取到轻量级锁; 线程执行完,解锁时,只须要移除栈帧中的lockRecord即可,而不必批改markWord中的内容。 轻量级锁 -> 重量级锁设置失败,则证实有竞争,此时会进入自旋状态。 线程超过10次自旋, 或者自旋线程数超过CPU核数的一半,(JDK1.6之后,退出自适应自旋 Adapative Self Spinning , JVM本人管制)。就会降级为重量级锁。 降级重量级锁: 向操作系统申请资源,CPU从3级-0级零碎调用,线程挂起,进入期待队列,期待操作系统的调度,而后再映射回用户空间 所以降级为重量级锁后,用户线程被零碎线程挂起,须要从用户态到内核态的转换。这也是最开始说synchronized重,性能差的起因! 总结:synchronized锁降级过程是单向的,不可逆;降级过程围绕锁对象中markWord的内容变动;每种锁都适应不同的场景,比方偏差锁实用于同一个线程屡次进入同步代码的状况,轻量级锁实用竞争小,且同步执行工夫短(自旋一会儿就能获取到锁)的状况对了,synchronized是可重入的,这点不光能够从偏差锁看进去,即便降级到重量级锁,也是反对的

June 18, 2022 · 1 min · jiezi

关于synchronized:Synchronized锁及其膨胀

一、序言在并发编程中,synchronized锁因其应用简略,在线程间同步被广泛应用。上面对其原理及锁降级过程进行探索。 二、如何应用1、润饰实例办法当实例办法被synchronized润饰时,通过以后实例调用此办法的所有线程共用一把锁,不同对象调用此办法线程间互不影响。 public class A { public synchronized void func() { }}当应用synchronized锁润饰实例办法,锁增加在以后类的实例上,有多少个实例可增加多少把锁。 2、润饰代码块润饰代码块比润饰办法颗粒度更小。当实例办法代码块被synchronized润饰时,通过以后实例调用此办法的所有线程共用一把锁,不同对象调用此办法线程间互不影响。 public class B { public void func() { synchronized (this) { } }}当应用synchronized锁润饰代码块,锁增加在以后类的实例上,有多少个实例可增加多少把锁。 3、润饰静态方法当静态方法被synchronized润饰时,整个JVM所有调用此办法的线程均受同一个锁的束缚。 public class C { public static synchronized void func() { }}当应用synchronized锁润饰静态方法,锁增加在以后类的类对象上,最多增加一把锁。 非必要不应用synchronized润饰静态方法三、锁的降级Java 8所应用的synchronized锁是通过优化后的,存在偏差锁、轻量级锁、重量级锁等状态。 (一)偏差锁线程间不存在锁的竞争行为,至少只有一个线程有获取锁的需要,常见场景为单线程程序。 1、识别方法判断是不是偏差锁的标识是查看调用此办法的线程是否有且仅有一个。 在多线程编程里,被锁润饰的办法仅被繁多线程调用简直不存在,因而偏差锁比拟鸡肋:如果可能明确繁多线程调用指标办法,应用无锁编程更为适合。 2、性能比拟无锁与偏差锁的性能差别十分靠近,简直能够忽略不计。 (二)轻量级锁线程间存在锁的伪竞争行为,即同一时刻相对不会存在两个线程申请获取锁,各线程只管都有应用锁的需要,然而是交替应用锁。 1、识别方法当有两个及以上线程调用被锁润饰的办法时,那么至多能确定是轻量级锁。 2、性能比拟轻量级锁因为同一时刻不存在两个线程相互竞争锁,因而不存在线程阻塞-唤醒的上下文切换,因而性能绝对重量级锁要高很多。 (三)重量级锁线程间存在锁的实质性竞争行为,线程间都有获取锁的需要,然而工夫不可交织,互斥锁的阻塞期待。 1、识别方法当可能必定至多有两个及以上线程调用被锁润饰的办法时,线程调用办法是随机的,那么大概率是重量级锁。 2、性能比拟重量级锁因为波及到线程阻塞-唤醒的上下文切换,造成相比拟与无锁状态,效率低很多。 四、其它内容(一)锁的性质1、公平性synchronized锁是非偏心锁,没有FIFO队列机制保障竞争锁的线程肯定有几率取得锁。 2、重入性synchronized锁是可重入锁,可重入意味着嵌套调用不会产生死锁问题。 3、乐(悲)观锁synchronized锁是一种乐观锁,通过加锁实现线程间同步。 (二)了解重量级锁在多线程环境下,如果应用synchronized锁,那么大概率会降级到重量级锁。偏差锁和轻量级锁非刻意为之,很难存在,更大的意义是比照帮忙了解重量级锁的性能。 重量级锁只管会对性能产生很大影响,然而仍旧是解决线程间同步的无效伎俩。 1、选用锁的倡议当被锁润饰的办法或者代码块执行工夫较长时,选用基于线程阻塞-唤醒切换上下文的形式进行线程同步效率绝对较高。 当被锁润饰的办法或者代码块执行工夫较短时,应选用其它代替锁,比方自旋锁等。 (三)了解synchronized锁在理论多线程场景开发中,synchronized锁大概率会降级到重量级锁,因其单向降级的特点,重量级状态的synchronized锁可能会对理论业务的并发产生不利影响,手动选用其它锁可能会更适合。 synchronized锁仅可用于解决同一过程内不同线程间同步,对于分布式我的项目跨进城线程同步依赖于分布式锁,synchronized锁更多的意义是了解锁的过程。 喜爱本文点个♥️赞♥️反对一下,如有须要,可通过微信dream4s与我分割。相干源码在GitHub,视频解说在B站,本文珍藏在博客天地。

April 22, 2022 · 1 min · jiezi

关于synchronized:深入JVM内置锁-synchronized-底层

前言上一章节带着大家理解了Java对象头的组成,本节带着大家理解synchronized 关键字的底层原理以及锁的降级过程 synchronized原理详解synchronized内置锁是一种对象锁(锁的是对象而非援用),作用粒度是对象,能够用来实现对临界资源的同步互斥拜访,是可重入的 什么是Monitor在Java虚拟机(HotSpot)中,Monitor是由ObjectMonitor实现的。Synchronized的对象锁,MarkWord锁标识位为10,其中指针指向的是Monitor对象的起始地址。其次要数据结构如下 ObjectMonitor() { _header = NULL; _count = 0; // 记录个数 _waiters = 0, _recursions = 0; _object = NULL; _owner = NULL; _WaitSet = NULL; // 处于wait状态的线程,会被退出到_WaitSet _WaitSetLock = 0 ; _Responsible = NULL ; _succ = NULL ; _cxq = NULL ; FreeNext = NULL ; _EntryList = NULL ; // 处于期待锁block状态的线程,会被退出到该列表 _SpinFreq = 0 ; _SpinClock = 0 ; OwnerIsThread = 0 ; }ObjectMonitor中有两个队列,_WaitSet 和 _EntryList,用来保留ObjectWaiter对象列表( 每个期待锁的线程都会被封装成ObjectWaiter对象 ),_owner指向持有ObjectMonitor对象的线程,当多个线程同时拜访一段同步代码时: ...

April 19, 2022 · 1 min · jiezi

关于synchronized:java开发技术之synchronized的使用浅析

synchronized 这个关键字的重要性显而易见,简直能够说是并发、多线程必须会问到的关键字了。synchronized 会波及到锁、降级降级操作、锁的撤销、对象头等。所以了解 synchronized 十分重要,本篇文章就带你从 synchronized 的根本用法、再到 synchronized 的深刻了解,对象头等,为你揭开 synchronized 的面纱。浅析 synchronizedsynchronized 是 Java 并发模块 十分重要的关键字,它是 Java 内建的一种同步机制,代表了某种外在锁定的概念,当一个线程对某个共享资源加锁后,其余想要获取共享资源的线程必须进行期待,synchronized 也具备互斥和排他的语义。什么是互斥?咱们想必小时候都玩儿过磁铁,磁铁会有正负极的概念,同性相斥异性相吸,相斥相当于就是一种互斥的概念,也就是两者互不相容。 synchronized 也是一种独占的关键字,然而它这种独占的语义更多的是为了减少线程安全性,通过独占某个资源以达到互斥、排他的目标。在理解了排他和互斥的语义后,咱们先来看一下 synchronized 的用法,先来理解用法,再来理解底层实现。synchronized 的应用对于 synchronized 想必你应该都大抵理解过• synchronized 润饰实例办法,相当于是对类的实例进行加锁,进入同步代码前须要取得以后实例的锁• synchronized 润饰静态方法,相当于是对类对象进行加锁• synchronized 润饰代码块,相当于是给对象进行加锁,在进入代码块前须要先取得对象的锁 上面咱们针对每个用法进行解释synchronized 润饰实例办法synchronized 润饰实例办法,实例办法是属于类的实例。synchronized 润饰的实例办法相当于是对象锁。上面是一个 synchronized 润饰实例办法的例子。public synchronized void method(){ // ...}像如上述 synchronized 润饰的办法就是实例办法,上面咱们通过一个残缺的例子来认识一下 synchronized 润饰实例办法public class TSynchronized implements Runnable{ static int i = 0;public synchronized void increase(){ i++; System.out.println(Thread.currentThread().getName());}@Overridepublic void run() { for(int i = 0;i < 1000;i++) { increase(); }}public static void main(String[] args) throws InterruptedException { TSynchronized tSynchronized = new TSynchronized(); Thread aThread = new Thread(tSynchronized); Thread bThread = new Thread(tSynchronized); aThread.start(); bThread.start(); aThread.join(); bThread.join(); System.out.println("i = " + i);}}下面输入的后果 i = 2000 ,并且每次都会打印以后现成的名字来解释一下下面代码,代码中的 i 是一个动态变量,动态变量也是全局变量,动态变量存储在办法区中。increase 办法由 synchronized 关键字润饰,然而没有应用 static 关键字润饰,示意 increase 办法是一个实例办法,每次创立一个 TSynchronized 类的同时都会创立一个 increase 办法,increase 办法中只是打印进去了以后拜访的线程名称。Synchronized 类实现了 Runnable 接口,重写了 run 办法,run 办法外面就是一个 0 - 1000 的计数器,这个没什么好说的。在 main 办法中,new 出了两个线程,别离是 aThread 和 bThread,Thread.join 示意期待这个线程解决完结。这段代码次要的作用就是判断 synchronized 润饰的办法可能具备独占性。synchronized 润饰静态方法synchronized 润饰静态方法就是 synchronized 和 static 关键字一起应用public static synchronized void increase(){}当 synchronized 作用于静态方法时,java培训示意的就是以后类的锁,因为静态方法是属于类的,它不属于任何一个实例成员,因而能够通过 class 对象管制并发拜访。这里须要留神一点,因为 synchronized 润饰的实例办法是属于实例对象,而 synchronized 润饰的静态方法是属于类对象,所以调用 synchronized 的实例办法并不会阻止拜访 synchronized 的静态方法。 ...

September 29, 2021 · 4 min · jiezi

关于synchronized:使用了synchronized竟然还有线程安全问题

实战中受过的伤,能力领悟的更透彻,二师兄带你剖析实战案例。线程平安问题始终是零碎亘古不变的痛点。这不,最近在我的项目中发了一个谬误应用线程同步的案例。外表上看曾经应用了同步机制,所有岁月静好,但实际上线程同步却毫无作用。 对于线程平安的问题,基本上就是在挖坑与填坑之间博弈,这也是为什么面试中线程平安必不可少的起因。上面,就来给大家剖析一下这个案例。 有隐患的代码先看一个脱敏的代码实例。代码要解决的业务逻辑很简略,就是多线程拜访一个单例对象的成员变量,对其进行自增解决。 SyncTest类实现了Runnable接口,run办法中解决业务逻辑。在run办法中通过synchronized来保障线程平安问题,在main办法中创立一个SyncTest类的对象,两个线程同时操作这一个对象。 public class SyncTest implements Runnable { private Integer count = 0; @Override public void run() { synchronized (count) { System.out.println(new Date() + " 开始休眠" + Thread.currentThread().getName()); count++; try { Thread.sleep(10000); System.out.println(new Date() + " 完结休眠" + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) throws InterruptedException { SyncTest test = new SyncTest(); new Thread(test).start(); Thread.sleep(100); new Thread(test).start(); }}在上述代码中,两个线程拜访SyncTest的同一个对象,并对该对象的count属性进行自增操作。因为是多线程,那就要保障count++的线程平安。 ...

July 26, 2021 · 2 min · jiezi

关于synchronized:详解synchronized与Lock的区别与使用

技术点: 1、线程与过程: 在开始之前先把过程与线程进行辨别一下,一个程序起码须要一个过程,而一个过程起码须要一个线程。关系是线程–>过程–>程序的大抵组成构造。所以线程是程序执行流的最小单位,而过程是零碎进行资源分配和调度的一个独立单位。以下咱们所有探讨的都是建设在线程根底之上。 2、Thread的几个重要办法: 咱们先理解一下Thread的几个重要办法。a、start()办法,调用该办法开始执行该线程;b、stop()办法,调用该办法强制完结该线程执行;c、join办法,调用该办法期待该线程完结。d、sleep()办法,调用该办法该线程进入期待。e、run()办法,调用该办法间接执行线程的run()办法,然而线程调用start()办法时也会运行run()办法,区别就是一个是由线程调度运行run()办法,一个是间接调用了线程中的run()办法!! 看到这里,可能有些人就会问啦,那wait()和notify()呢?要留神,其实wait()与notify()办法是Object的办法,不是Thread的办法!!同时,wait()与notify()会配合应用,别离示意线程挂起和线程复原。 这里还有一个很常见的问题,顺带提一下:wait()与sleep()的区别,简略来说wait()会开释对象锁而sleep()不会开释对象锁。这些问题有很多的材料,不再赘述。 3、线程状态: 线程总共有5大状态,通过下面第二个知识点的介绍,了解起来就简略了。 新建状态:新建线程对象,并没有调用start()办法之前 就绪状态:调用start()办法之后线程就进入就绪状态,然而并不是说只有调用start()办法线程就马上变为以后线程,在变为以后线程之前都是为就绪状态。值得一提的是,线程在睡眠和挂起中复原的时候也会进入就绪状态哦。 运行状态:线程被设置为以后线程,开始执行run()办法。就是线程进入运行状态 阻塞状态:线程被暂停,比如说调用sleep()办法后线程就进入阻塞状态 死亡状态:线程执行完结 4、锁类型 可重入锁:在执行对象中所有同步办法不必再次取得锁 可中断锁:在期待获取锁过程中可中断 偏心锁: 按期待获取锁的线程的等待时间进行获取,等待时间长的具备优先获取锁权力 读写锁:对资源读取和写入的时候拆分为2局部解决,读的时候能够多线程一起读,写的时候必须同步地写 synchronized与Lock的区别1、我把两者的区别分类到了一个表中,不便大家比照: 类别 synchronized Lock存在档次 Java的关键字,在jvm层面上 是一个类锁的开释 1、以获取锁的线程执行完同步代码,开释锁 2、线程执行产生异样,jvm会让线程开释锁 在finally中必须开释锁,不然容易造成线程死锁锁的获取 假如A线程取得锁,B线程期待。如果A线程阻塞,B线程会始终期待 分状况而定,Lock有多个锁获取的形式,具体上面会说道,大抵就是能够尝试取得锁,线程能够不必始终期待锁状态 无奈判断 能够判断锁类型 可重入 不可中断 非偏心 可重入 可判断 可偏心(两者皆可)性能 大量同步 大量同步或者,看到这里还对LOCK所知甚少,那么接下来,咱们进入LOCK的深刻学习。 Lock具体介绍与Demo以下是Lock接口的源码,笔者修剪之后的后果: public interface Lock { /** * Acquires the lock. */ void lock(); /** * Acquires the lock unless the current thread is * {@linkplain Thread#interrupt interrupted}. */ void lockInterruptibly() throws InterruptedException; /** * Acquires the lock only if it is free at the time of invocation. */ boolean tryLock(); /** * Acquires the lock if it is free within the given waiting time and the * current thread has not been {@linkplain Thread#interrupt interrupted}. */ boolean tryLock(long time, TimeUnit unit) throws InterruptedException; /** * Releases the lock. */ void unlock(); }从Lock接口中咱们能够看到次要有个办法,这些办法的性能从正文中能够看出:lock():获取锁,如果锁被暂用则始终期待 ...

July 22, 2021 · 3 min · jiezi

关于synchronized:乐观锁和悲观锁

乐观锁和乐观锁

June 10, 2021 · 1 min · jiezi

关于synchronized:验证synchronized锁升级时对象头变化全过程-springboot实战电商项目mall4j

springboot实战电商我的项目mall4j (https://gitee.com/gz-yami/mall4j) java开源商城零碎 验证synchronized锁降级时对象头变动全过程jdk版本:1.8 零碎:window10 64位 jvm 启动参数:-XX:BiasedLockingStartupDelay=0 (勾销提早加载偏差锁) 首先须要已知几个概念 java 非数组对象(一般对象)的内存构造 如果是 array 对象,则会再占用一个 length 空间(4 字节),记录数组的长度。 java object 的 markword 格局(64位虚拟机上) 3.synchronized 四锁降级流程以及何时降级(不赘述) 通过理论编码查看别离在这四个锁状态时,锁标记位是否相应变动 引入 jol 工具包 <dependency> <groupId>org.openjdk.jol</groupId> <artifactId>jol-core</artifactId> <version>0.9</version></dependency>无锁态 @Testpublic void test01() throws Exception { Object o = new Object(); System.out.println(ClassLayout.parseInstance(o).toPrintable());}执行后果 java.lang.Object object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 01 00 00 00 (00000101 00000000 00000000 00000000) (5) 4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) 8 4 (object header) e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243) 12 4 (loss due to the next object alignment)Instance size: 16 bytesSpace losses: 0 bytes internal + 4 bytes external = 4 bytes total第一、二行的 object header 是 markword 的内存,第三行的 object header 是 class pointer 的内容,第四行是对齐填充。 ...

May 13, 2021 · 4 min · jiezi

关于synchronized:13张图深入理解Synchronized

前言Java并发编程系列第二篇Synchronized,文章格调仍然是图文并茂,通俗易懂,本文带读者们由浅入深了解Synchronized,让读者们也能与面试官疯狂对线。 在并发编程中Synchronized始终都是元老级的角色,Jdk 1.6以前大家都称说它为重量级锁,绝对于J U C包提供的Lock,它会显得轻便,不过随着Jdk 1.6对Synchronized进行各种优化后,Synchronized性能曾经十分快了。 内容纲要 Synchronized应用形式Synchronized是Java提供的同步关键字,在多线程场景下,对共享资源代码段进行读写操作(必须蕴含写操作,光读不会有线程平安问题,因为读操作人造具备线程平安个性),可能会呈现线程平安问题,咱们能够应用Synchronized锁定共享资源代码段,达到互斥(mutualexclusion)成果,保障线程平安。 共享资源代码段又称为临界区(critical section),保障临界区互斥,是指执行临界区(critical section)的只能有一个线程执行,其余线程阻塞期待,达到排队成果。 Synchronized的食用形式有三种 润饰一般函数,监视器锁(monitor)便是对象实例(this)润饰动态动态函数,视器锁(monitor)便是对象的Class实例(每个对象只有一个Class实例)润饰代码块,监视器锁(monitor)是指定对象实例一般函数一般函数应用Synchronized的形式很简略,在拜访权限修饰符与函数返回类型间加上Synchronized。 多线程场景下,thread与threadTwo两个线程执行incr函数,incr函数作为共享资源代码段被多线程读写操作,咱们将它称为临界区,为了保障临界区互斥,应用Synchronized润饰incr函数即可。 public class SyncTest { private int j = 0; /** * 自增办法 */ public synchronized void incr(){ //临界区代码--start for (int i = 0; i < 10000; i++) { j++; } //临界区代码--end } public int getJ() { return j; }}public class SyncMain { public static void main(String[] agrs) throws InterruptedException { SyncTest syncTest = new SyncTest(); Thread thread = new Thread(() -> syncTest.incr()); Thread threadTwo = new Thread(() -> syncTest.incr()); thread.start(); threadTwo.start(); thread.join(); threadTwo.join(); //最终打印后果是20000,如果不应用synchronized润饰,就会导致线程平安问题,输入不确定后果 System.out.println(syncTest.getJ()); }}代码非常简略,incr函数被synchronized润饰,函数逻辑是对j进行10000次累加,两个线程执行incr函数,最初输入j后果。 ...

May 7, 2021 · 3 min · jiezi

关于synchronized:synchronized-是王的后宫总管线程是王妃

synchronized 是王的后宫总管,线程是王妃关注 「码哥字节」每一篇都是硬核,读者群已开明,后盾回复 「加群」一起成长。如果 synchronized 是「王」身边的「大总管」,那么 Thread 就像是他后宫的王妃。「王」每日只能抉择一个==王妃==陪伴,王妃们会千方百计争宠取得陪伴权,大总管须要通过肯定的伎俩让王「翻牌」一个「王妃」与王相伴。 在JMM 透析 volatile 与 synchronized 原理一文中解说了内存模型与并发实现原理的深层关系,今日听「码哥」胡说八道解开 synchronized 大总管如何调度「王妃」陪伴「王」,王妃不同状态的变动到底经验了什么?且看 synchronized 大总管又采取了哪些伎俩更加高效「翻牌」一个王妃,宫斗还有 30 秒达到战场!!! [toc] 「码哥字节」讲通过几个故事,通俗易懂的让读者敌人齐全把握 synchronized 的锁优化(偏差锁 -> 轻量级锁 -> 重量级锁)原理以及线程在 6 种状态之间转换的神秘。 形象出三个概念:Thread 对应后宫佳丽「王妃」,synchronized 是后宫大总管负责安顿调度王妃,「王」则是被王妃们想要竞争的资源。 王妃的 6 种状态后宫佳丽等级森严,王妃们在这场权贵的游戏中每个人的目标都是为获取「王」钟爱,在游戏中本身的状态也随着变动。 就像生物从出世到长大、最终死亡的过程一样,「王妃」也有本人的生命周期,在 王妃的生命周期中一共有 6 种状态。 New(新入宫):Thread state for a thread which has not yet started.Runnable 可运行、就绪:(身材舒服,筹备好了),Java 中的 Runable 状态对应操作系统线程状态中的两种状态,别离是 Running 和 Ready,也就是说,Java 中处于 Runnable 状态的线程有可能正在执行,也有可能没有正在执行,正在期待被调配 CPU 资源。Blocked 阻塞(身材欠佳、被打入冷宫)WAITING(期待):(期待传唤)Timed Waiting(计时期待):在门外计时期待Terminated(终止):嗝屁 王妃在任意时刻只能是其中的一种状态,通过 getState() 办法获取线程状态。 ...

December 17, 2020 · 3 min · jiezi