Java中的各种锁

108 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第25天,点击查看活动详情

Java中的各种锁

今天我们就一起来学习一下,java中的各种锁。

前言

相信java中大家最熟悉的锁莫过于synchronized锁了,这个可以说是大家提起java中的并发编程必然会提到的锁,然而java中的锁并不只是只有synchronized锁,它还是有其他的锁的,比如说reentrantlock、CountDownLatch、CyclicBarrier、Phaser、ReadWriteLock、Semaphore、Exchanger等。

接下来,咱们就详细地开始学习一下,Java中的其他锁,来完善一下我们的知识体系。

synchronized锁

对于这个锁大家肯定不陌生了,synchronized中呢,并不是一上来就上锁的,它有一个锁升级的过程。

下面我们还是简述一下synchronized锁升级的一个简要过程:

一个线程来的时候,是偏向锁;

两个线程来的时候,是自旋锁;

自旋10次后还没得到锁,就是操作系统层面的重量级锁了。

reentrantlock

reentrantlock的作用是可以替代synchronized的作用的,但是需要特别注意一点就是:

synchronized锁在遇到异常的时候,锁会自动释放的;但是reentrantlock是不会自动释放锁的,所以在使用了reentrantlock的时候,一定要想好在哪里执行释放锁的操作(确保无论代码是否正常运行,最后都可以释放锁)

CountDownLatch

这个锁是一个“倒数锁”,在定义latch的时候,指定一个长度,在没倒数到0之前,线程都停留在 latch.await();语句中,无法往下执行。

CyclicBarrier

“满人发车”:在线程数没达到指定数量之前,所有线程都停留在 barrier.await();语句中,无法向下执行。

Phaser

“阶段锁”:可以将过程划分为多个阶段,每次在进入下一个阶段的时候,都需要等完所有线程再进入;当前如果某些线程不需要参加后面的阶段,就可以执行取消注册的命令 phaser.arriveAndDeregister()

ReadWriteLock

“读写锁”:读锁和写锁(共享锁和排他锁)

像synchronized锁是一旦锁上,其他线程是无法获取锁的;但是如果是读锁(共享锁)它是允许多个读线程共同享有的;在某些场景下,ReadWriteLock 的效率会比synchronized高效不少。

Semaphore

“信号量”:设置信号量的数值是多少,就有多少个线程可以同时获得锁,一旦Semaphore为0,则其他线程无法继续。

Exchanger

“交换锁”:这个锁是很特别的,它只针对于两个线程之间的,用于线程间交换某个数据。