网站首页 > java教程 正文
并发篇:一网打尽 Java 中的 8 种 ‘锁’ 事
最近在开发项目中遇到了资源同步的问题,导致服务器卡顿,优化的时候使用了锁的机制。在 Java 中,锁(Lock)是实现并发控制的重要机制,它可以控制多个线程对共享资源的访问。在 Java 中,有多种类型的锁可以使用,每种锁都有其适用的场景和优劣点。本文将介绍 Java 中的 8 种常见锁,包括 synchronized、ReentrantLock、ReentrantReadWriteLock、StampedLock、LockSupport、Semaphore、CountDownLatch 和 CyclicBarrier,并给出相应的 Java 代码示例。
大家好,这里是互联网技术学堂,如果你有兴趣,那就点赞、关注、分享吧。
按照锁的特性和设计来划分,分为如下几类:
1、公平锁/非公平锁
2、可重入锁
3、独享锁/共享锁
4、互斥锁/读写锁
5、乐观锁/悲观锁
6、分段锁
7、偏向锁/轻量级锁/重量级锁
8、自旋锁(java.util.concurrent包下的几乎都是利用锁)
synchronized
synchronized 是 Java 中最常用的锁之一,它是一种内置锁,可以用来实现原子操作和保护临界区。synchronized 的使用方式很简单,只需要在方法或代码块前加上 synchronized 关键字即可。
public synchronized void addCount(){
count++;
}
ReentrantLock
ReentrantLock 是一种可重入锁,它与 synchronized 类似,但是提供了更多的灵活性和功能,比如可以设置公平锁和非公平锁、可中断锁、可限时锁等。ReentrantLock 必须在 finally 块中释放锁。
ReentrantLock lock = new ReentrantLock();
public void addCount(){
lock.lock();
try{
count++;
} finally {
lock.unlock();
}
}
ReentrantReadWriteLock
ReentrantReadWriteLock 是一种读写锁,它可以同时允许多个线程读共享资源,但只允许一个线程写共享资源。它通过分离读锁和写锁来提高并发性能,读写锁的使用方式与 ReentrantLock 类似。
ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
ReadWriteLock.ReadLock readLock = rwl.readLock();
ReadWriteLock.WriteLock writeLock = rwl.writeLock();
public void read(){
readLock.lock();
try{
// 读操作
} finally {
readLock.unlock();
}
}
public void write(){
writeLock.lock();
try{
// 写操作
} finally {
writeLock.unlock();
}
}
StampedLock
StampedLock 是 Java 8 新增的一种锁,它是一种乐观锁,可以提高读操作的并发性能。StampedLock 支持三种锁模式:写锁、悲观读锁和乐观读锁,它们的使用方式与 ReentrantReadWriteLock 类似。
StampedLock sl = new StampedLock();
public void read(){
long stamp = sl.tryOptimisticRead();
// 读操作
if(!sl.validate(stamp)){
stamp = sl.readLock();
try{
// 读操作
} finally {
sl.unlockRead(stamp);
}
}
}
public void write(){
long stamp = sl.writeLock();
try{
// 写操作
} finally {
sl.unlockWrite(stamp);
}
}
LockSupport
LockSupport 是 Java 中提供的另一种锁机制,它可以用来挂起和恢复线程的执行,类似于 wait() 和 notify() 方法。LockSupport 提供了 park() 和 unpark() 方法来挂起和恢复线程的执行。
Thread thread = new Thread(() -> {
// 线程执行前
LockSupport.park(); // 挂起线程
// 线程执行后
});
thread.start();
LockSupport.unpark(thread); // 恢复线程执行
Semaphore
Semaphore 是一种计数信号量,它可以控制同时访问某个共享资源的线程数。Semaphore 可以被看作是一种权限机制,只有获得许可证的线程才能访问共享资源。
Semaphore semaphore = new Semaphore(10); // 最多允许 10 个线程访问共享资源
public void accessResource() throws InterruptedException {
semaphore.acquire(); // 获取许可证
try{
// 访问共享资源
} finally {
semaphore.release(); // 释放许可证
}
}
CountDownLatch
CountDownLatch 是一种同步工具,它可以让一个线程等待多个线程完成后再继续执行。CountDownLatch 维护了一个计数器,当计数器的值变为 0 时,等待线程就可以继续执行。
CountDownLatch latch = new CountDownLatch(10); // 计数器的初始值为 10
public void doTask(){
// 执行任务
latch.countDown(); // 计数器减 1
}
public void await() throws InterruptedException {
latch.await(); // 等待计数器变为 0
}
CyclicBarrier
CyclicBarrier 是一种同步工具,它可以让多个线程在指定的屏障点处等待,直到所有线程都到达后再一起继续执行。CyclicBarrier 维护了一个计数器和一个屏障点,当计数器的值变为 0 时,所有等待的线程都可以继续执行。
CyclicBarrier barrier = new CyclicBarrier(10); // 计数器的初始值为 10
public void doTask() throws InterruptedException, BrokenBarrierException {
// 执行任务
barrier.await(); // 等待其他线程到达屏障点
}
public void reset(){
barrier.reset(); // 重置屏障点和计数器
}
以上就是 Java 中的 8 种常见锁,它们各有优缺点,可以根据具体的场景选择适合的锁来实现并发控制。
- 上一篇: Java锁机制:让程序井然有序
- 下一篇: Java中的锁原理、锁优化、CAS、AQS
猜你喜欢
- 2025-05-15 Java并发编程(23)锁消除,锁粗化,偏向锁,轻量级锁,自旋锁
- 2025-05-15 在Java中如何用一把锁保护多个资源?
- 2025-05-15 【多线程系列】终于懂了 Java 中的各种锁
- 2025-05-15 Java有哪些锁,具体应用场景、代码实现以及优缺点对比有哪些
- 2025-05-15 Java中的锁原理、锁优化、CAS、AQS
- 2025-05-15 Java锁机制:让程序井然有序
- 2025-05-15 Java锁机制的那些事儿
- 2025-05-15 Java内置锁:synchronized
- 2025-05-15 探秘Java中的分布式锁:优雅地协调分布式系统
- 2025-05-15 Java高并发编程中的锁优化:锁的那些事儿
你 发表评论:
欢迎- 05-15java使用iText解析PDF文件
- 05-15java 将pdf 形成的图片,每页一张图片 保存为pdf文件
- 05-15Java学习123——虚拟方法调用(Virtual Method Invocation)
- 05-15什么是JNI?为什么会有Native层?如何使用?
- 05-15Socket通信
- 05-15译文:理解Java中的弱引用
- 05-15Java 调用 DeepSeek 模型的完整示例及特点
- 05-15Java 对象和类
- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)