7474
7575因为监视器锁(monitor)是依赖于底层的操作系统的 ` Mutex Lock ` 来实现的,Java 的线程是映射到操作系统的原生线程之上的。如果要挂起或者唤醒一个线程,都需要操作系统帮忙完成,而操作系统实现线程之间的切换时需要从用户态转换到内核态,这个状态之间的转换需要相对比较长的时间,时间成本相对较高。
7676
77- 庆幸的是在 Java 6 之后 Java 官方对从 JVM 层面对 synchronized 较大优化,所以现在的 synchronized 锁效率也优化得很不错了。JDK1.6 对锁的实现引入了大量的优化,如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁等技术来减少锁操作的开销。
77+ 庆幸的是在 Java 6 之后 Java 官方对从 JVM 层面对 ` synchronized ` 较大优化,所以现在的 ` synchronized ` 锁效率也优化得很不错了。JDK1.6 对锁的实现引入了大量的优化,如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁等技术来减少锁操作的开销。
7878
79- 所以,你会发现目前的话,不论是各种开源框架还是 JDK 源码都大量使用了 synchronized 关键字。
79+ 所以,你会发现目前的话,不论是各种开源框架还是 JDK 源码都大量使用了 ` synchronized ` 关键字。
8080
8181### 1.2. 说说自己是怎么使用 synchronized 关键字
8282
@@ -296,9 +296,9 @@ JDK1.6 对锁的实现引入了大量的优化,如偏向锁、轻量级锁、
296296
297297` synchronized ` 关键字和 ` volatile ` 关键字是两个互补的存在,而不是对立的存在!
298298
299- - ** volatile 关键字** 是线程同步的** 轻量级实现** ,所以** volatile 性能肯定比 synchronized 关键字要好** 。但是** volatile 关键字只能用于变量而 synchronized 关键字可以修饰方法以及代码块** 。
300- - ** volatile 关键字能保证数据的可见性,但不能保证数据的原子性。synchronized 关键字两者都能保证。**
301- - ** volatile 关键字主要用于解决变量在多个线程之间的可见性,而 synchronized 关键字解决的是多个线程之间访问资源的同步性。**
299+ - ** ` volatile ` 关键字** 是线程同步的** 轻量级实现** ,所以** ` volatile ` 性能肯定比` synchronized ` 关键字要好** 。但是** ` volatile ` 关键字只能用于变量而 ` synchronized ` 关键字可以修饰方法以及代码块** 。
300+ - ** ` volatile ` 关键字能保证数据的可见性,但不能保证数据的原子性。` synchronized ` 关键字两者都能保证。**
301+ - ** ` volatile ` 关键字主要用于解决变量在多个线程之间的可见性,而 ` synchronized ` 关键字解决的是多个线程之间访问资源的同步性。**
302302
303303## 3. ThreadLocal
304304
@@ -814,7 +814,7 @@ pool-1-thread-1 End. Time = Tue Nov 12 20:59:54 CST 2019
814814
815815### 5.1. 介绍一下 Atomic 原子类
816816
817- Atomic 翻译成中文是原子的意思。在化学上,我们知道原子是构成一般物质的最小单位,在化学反应中是不可分割的。在我们这里 Atomic 是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰。
817+ ` Atomic ` 翻译成中文是原子的意思。在化学上,我们知道原子是构成一般物质的最小单位,在化学反应中是不可分割的。在我们这里 Atomic 是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰。
818818
819819所以,所谓原子类说简单点就是具有原子/原子操作特征的类。
820820
@@ -828,29 +828,29 @@ Atomic 翻译成中文是原子的意思。在化学上,我们知道原子是
828828
829829使用原子的方式更新基本类型
830830
831- - AtomicInteger:整形原子类
832- - AtomicLong:长整型原子类
833- - AtomicBoolean:布尔型原子类
831+ - ` AtomicInteger ` :整形原子类
832+ - ` AtomicLong ` :长整型原子类
833+ - ` AtomicBoolean ` :布尔型原子类
834834
835835** 数组类型**
836836
837837使用原子的方式更新数组里的某个元素
838838
839- - AtomicIntegerArray:整形数组原子类
840- - AtomicLongArray:长整形数组原子类
841- - AtomicReferenceArray:引用类型数组原子类
839+ - ` AtomicIntegerArray ` :整形数组原子类
840+ - ` AtomicLongArray ` :长整形数组原子类
841+ - ` AtomicReferenceArray ` :引用类型数组原子类
842842
843843** 引用类型**
844844
845- - AtomicReference:引用类型原子类
846- - AtomicStampedReference:原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于解决原子的更新数据和数据的版本号,可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。
847- - AtomicMarkableReference :原子更新带有标记位的引用类型
845+ - ` AtomicReference ` :引用类型原子类
846+ - ` AtomicStampedReference ` :原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于解决原子的更新数据和数据的版本号,可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。
847+ - ` AtomicMarkableReference ` :原子更新带有标记位的引用类型
848848
849849** 对象的属性修改类型**
850850
851- - AtomicIntegerFieldUpdater:原子更新整形字段的更新器
852- - AtomicLongFieldUpdater:原子更新长整形字段的更新器
853- - AtomicReferenceFieldUpdater:原子更新引用类型字段的更新器
851+ - ` AtomicIntegerFieldUpdater ` :原子更新整形字段的更新器
852+ - ` AtomicLongFieldUpdater ` :原子更新长整形字段的更新器
853+ - ` AtomicReferenceFieldUpdater ` :原子更新引用类型字段的更新器
854854
855855### 5.3. 讲讲 AtomicInteger 的使用
856856
@@ -916,11 +916,11 @@ CAS 的原理是拿期望的值和原本的一个值作比较,如果相同则
916916
917917### 6.1. AQS 介绍
918918
919- AQS 的全称为(AbstractQueuedSynchronizer),这个类在 java.util.concurrent.locks 包下面。
919+ AQS 的全称为(` AbstractQueuedSynchronizer ` ),这个类在` java.util.concurrent.locks ` 包下面。
920920
921921![ AQS类] ( https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/AQS类.png )
922922
923- AQS 是一个用来构建锁和同步器的框架,使用 AQS 能简单且高效地构造出应用广泛的大量的同步器,比如我们提到的 ReentrantLock, Semaphore,其他的诸如 ReentrantReadWriteLock, SynchronousQueue, FutureTask 等等皆是基于 AQS 的。当然,我们自己也能利用 AQS 非常轻松容易地构造出符合我们自己需求的同步器。
923+ AQS 是一个用来构建锁和同步器的框架,使用 AQS 能简单且高效地构造出应用广泛的大量的同步器,比如我们提到的 ` ReentrantLock ` , ` Semaphore ` ,其他的诸如 ` ReentrantReadWriteLock ` , ` SynchronousQueue ` , ` FutureTask ` 等等皆是基于 AQS 的。当然,我们自己也能利用 AQS 非常轻松容易地构造出符合我们自己需求的同步器。
924924
925925### 6.2. AQS 原理分析
926926
@@ -1012,9 +1012,9 @@ tryReleaseShared(int)//共享方式。尝试释放资源,成功则返回true
10121012
10131013### 6.3. AQS 组件总结
10141014
1015- - ** Semaphore(信号量)-允许多个线程同时访问:** synchronized 和 ReentrantLock 都是一次只允许一个线程访问某个资源,Semaphore(信号量)可以指定多个线程同时访问某个资源。
1016- - ** CountDownLatch (倒计时器):** CountDownLatch 是一个同步工具类,用来协调多个线程之间的同步。这个工具通常用来控制线程等待,它可以让某一个线程等待直到倒计时结束,再开始执行。
1017- - ** CyclicBarrier(循环栅栏):** CyclicBarrier 和 CountDownLatch 非常类似,它也可以实现线程间的技术等待,但是它的功能比 CountDownLatch 更加复杂和强大。主要应用场景和 CountDownLatch 类似。CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。CyclicBarrier 默认的构造方法是 CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用 await()方法告诉 CyclicBarrier 我已经到达了屏障,然后当前线程被阻塞。
1015+ - ** ` Semaphore ` (信号量)-允许多个线程同时访问:** ` synchronized ` 和 ` ReentrantLock ` 都是一次只允许一个线程访问某个资源,` Semaphore ` (信号量)可以指定多个线程同时访问某个资源。
1016+ - ** ` CountDownLatch ` (倒计时器):** ` CountDownLatch ` 是一个同步工具类,用来协调多个线程之间的同步。这个工具通常用来控制线程等待,它可以让某一个线程等待直到倒计时结束,再开始执行。
1017+ - ** ` CyclicBarrier ` (循环栅栏):** ` CyclicBarrier ` 和 ` CountDownLatch ` 非常类似,它也可以实现线程间的技术等待,但是它的功能比 ` CountDownLatch ` 更加复杂和强大。主要应用场景和 ` CountDownLatch ` 类似。` CyclicBarrier ` 的字面意思是可循环使用(` Cyclic ` )的屏障(` Barrier ` )。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。` CyclicBarrier ` 默认的构造方法是 ` CyclicBarrier(int parties) ` ,其参数表示屏障拦截的线程数量,每个线程调用 ` await() ` 方法告诉 ` CyclicBarrier ` 我已经到达了屏障,然后当前线程被阻塞。
10181018
10191019### 6.4. 用过 CountDownLatch 么?什么场景下用的?
10201020
0 commit comments