您的位置:首页 > 科技 > IT业 > 定制开发软件的公司_全面的网站制作_外媒头条最新消息_企业网站seo案例分析

定制开发软件的公司_全面的网站制作_外媒头条最新消息_企业网站seo案例分析

2025/4/1 0:58:32 来源:https://blog.csdn.net/qu1210/article/details/146611283  浏览:    关键词:定制开发软件的公司_全面的网站制作_外媒头条最新消息_企业网站seo案例分析
定制开发软件的公司_全面的网站制作_外媒头条最新消息_企业网站seo案例分析

Java 锁的使用详解

Java 提供了多种锁机制来处理并发编程中的同步问题。下面我将通过代码示例来展示各种锁的使用方法和特点。

锁的选择指南

以下是选择合适锁的指南:

在这里插入图片描述

基本锁类型演示

// 由于这是在 Node.js 环境中模拟 Java 锁的概念,我们将使用注释和伪代码来解释console.log("Java 锁的使用详解\n");console.log("1. synchronized 关键字 (内置锁)");
console.log(`
public class SynchronizedExample {private int count = 0;// 同步方法 - 锁定当前对象实例public synchronized void increment() {count++;}// 同步代码块 - 锁定指定对象public void incrementBlock() {synchronized(this) {count++;}}// 静态同步方法 - 锁定类对象public static synchronized void staticMethod() {// 操作静态资源}
}
`);console.log("\n2. ReentrantLock (可重入锁)");
console.log(`
import java.util.concurrent.locks.ReentrantLock;public class ReentrantLockExample {private final ReentrantLock lock = new ReentrantLock();private int count = 0;public void increment() {// 获取锁lock.lock();try {count++;} finally {// 在 finally 块中释放锁,确保锁一定会被释放lock.unlock();}}// 尝试获取锁,带超时public void incrementWithTimeout() {try {// 尝试在 1 秒内获取锁boolean acquired = lock.tryLock(1, TimeUnit.SECONDS);if (acquired) {try {count++;} finally {lock.unlock();}} else {// 获取锁失败的处理System.out.println("无法获取锁");}} catch (InterruptedException e) {Thread.currentThread().interrupt();}}
}
`);console.log("\n3. ReadWriteLock (读写锁)");
console.log(`
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;public class ReadWriteLockExample {private final ReadWriteLock rwLock = new ReentrantReadWriteLock();private int data = 0;// 读操作 - 可以多个线程同时读public int readData() {rwLock.readLock().lock();try {return data;} finally {rwLock.readLock().unlock();}}// 写操作 - 只能一个线程写,且写时不能读public void writeData(int newValue) {rwLock.writeLock().lock();try {data = newValue;} finally {rwLock.writeLock().unlock();}}
}
`);console.log("\n4. StampedLock (带版本号的锁)");
console.log(`
import java.util.concurrent.locks.StampedLock;public class StampedLockExample {private final StampedLock lock = new StampedLock();private double x, y;// 写操作 - 独占模式public void move(double deltaX, double deltaY) {long stamp = lock.writeLock();try {x += deltaX;y += deltaY;} finally {lock.unlockWrite(stamp);}}// 读操作 - 乐观读public double distanceFromOrigin() {// 乐观读,不阻塞写操作long stamp = lock.tryOptimisticRead();double currentX = x;double currentY = y;// 检查读取期间是否有写操作发生if (!lock.validate(stamp)) {// 有写操作,切换到悲观读锁stamp = lock.readLock();try {currentX = x;currentY = y;} finally {lock.unlockRead(stamp);}}return Math.sqrt(currentX * currentX + currentY * currentY);}// 悲观读锁public double distanceFromOriginPessimistic() {long stamp = lock.readLock();try {return Math.sqrt(x * x + y * y);} finally {lock.unlockRead(stamp);}}
}
`);console.log("\n5. Condition (条件变量)");
console.log(`
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;public class ConditionExample {private final ReentrantLock lock = new ReentrantLock();private final Condition notFull = lock.newCondition();private final Condition notEmpty = lock.newCondition();private final Object[] items = new Object[100];private int putIndex, takeIndex, count;// 生产者方法public void put(Object x) throws InterruptedException {lock.lock();try {// 缓冲区已满,等待while (count == items.length) {notFull.await();}items[putIndex] = x;putIndex = (putIndex + 1) % items.length;count++;// 通知消费者有新数据notEmpty.signal();} finally {lock.unlock();}}// 消费者方法public Object take() throws InterruptedException {lock.lock();try {// 缓冲区为空,等待while (count == 0) {notEmpty.await();}Object x = items[takeIndex];takeIndex = (takeIndex + 1) % items.length;count--;// 通知生产者有空间notFull.signal();return x;} finally {lock.unlock();}}
}
`);console.log("\n6. Semaphore (信号量)");
console.log(`
import java.util.concurrent.Semaphore;public class SemaphoreExample {// 创建一个只允许5个线程同时访问的信号量private final Semaphore semaphore = new Semaphore(5);public void accessResource() {try {// 获取许可semaphore.acquire();try {// 访问资源System.out.println("访问资源中...");Thread.sleep(1000); // 模拟资源访问} finally {// 释放许可semaphore.release();}} catch (InterruptedException e) {Thread.currentThread().interrupt();}}// 尝试获取许可,不阻塞public void tryAccessResource() {boolean acquired = semaphore.tryAcquire();if (acquired) {try {// 访问资源System.out.println("访问资源中...");} finally {semaphore.release();}} else {System.out.println("无法获取许可,资源繁忙");}}
}
`);console.log("\n7. CountDownLatch (倒计时门闩)");
console.log(`
import java.util.concurrent.CountDownLatch;public class CountDownLatchExample {public void execute() throws InterruptedException {// 创建一个初始计数为3的CountDownLatchfinal CountDownLatch latch = new CountDownLatch(3);// 启动三个工作线程for (int i = 0; i < 3; i++) {final int taskId = i;new Thread(() -> {try {// 模拟任务执行System.out.println("任务 " + taskId + " 执行中...");Thread.sleep(1000);System.out.println("任务 " + taskId + " 完成");// 计数减一latch.countDown();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}).start();}// 主线程等待所有工作线程完成System.out.println("等待所有任务完成...");latch.await();System.out.println("所有任务已完成,继续执行主线程");}
}
`);console.log("\n8. CyclicBarrier (循环栅栏)");
console.log(`
import java.util.concurrent.CyclicBarrier;public class CyclicBarrierExample {public void execute() {// 创建一个CyclicBarrier,当3个线程到达栅栏时,执行指定的任务final CyclicBarrier barrier = new CyclicBarrier(3, () -> {System.out.println("所有线程都到达栅栏,执行栅栏动作");});// 启动三个工作线程for (int i = 0; i < 3; i++) {final int taskId = i;new Thread(() -> {try {System.out.println("线程 " + taskId + " 正在执行第一阶段");Thread.sleep(1000);// 第一个栅栏点System.out.println("线程 " + taskId + " 到达第一个栅栏");barrier.await();System.out.println("线程 " + taskId + " 正在执行第二阶段");Thread.sleep(1000);// 第二个栅栏点 (循环使用)System.out.println("线程 " + taskId + " 到达第二个栅栏");barrier.await();System.out.println("线程 " + taskId + " 完成所有工作");} catch (Exception e) {e.printStackTrace();}}).start();}}
}
`);console.log("\n9. Phaser (阶段器)");
console.log(`
import java.util.concurrent.Phaser;public class PhaserExample {public void execute() {// 创建一个初始参与者数量为1的Phaser (主线程)final Phaser phaser = new Phaser(1);// 创建并启动3个工作线程for (int i = 0; i < 3; i++) {final int taskId = i;// 注册一个参与者phaser.register();new Thread(() -> {try {System.out.println("线程 " + taskId + " 开始第一阶段");Thread.sleep(1000);// 到达第一阶段结束点,等待其他线程System.out.println("线程 " + taskId + " 完成第一阶段");phaser.arriveAndAwaitAdvance();System.out.println("线程 " + taskId + " 开始第二阶段");Thread.sleep(1000);// 到达第二阶段结束点,等待其他线程System.out.println("线程 " + taskId + " 完成第二阶段");phaser.arriveAndAwaitAdvance();System.out.println("线程 " + taskId + " 开始第三阶段");Thread.sleep(1000);// 完成所有阶段,取消注册System.out.println("线程 " + taskId + " 完成所有阶段");phaser.arriveAndDeregister();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}).start();}// 主线程等待所有工作线程完成第一阶段phaser.arriveAndAwaitAdvance();System.out.println("所有线程完成第一阶段");// 主线程等待所有工作线程完成第二阶段phaser.arriveAndAwaitAdvance();System.out.println("所有线程完成第二阶段");// 主线程等待所有工作线程完成第三阶段phaser.arriveAndAwaitAdvance();System.out.println("所有线程完成所有阶段");// 主线程取消注册phaser.arriveAndDeregister();}
}
`);console.log("\n10. 锁的最佳实践");
console.log(`
1. 尽量缩小同步范围,只锁定必要的代码块
2. 避免在持有锁的情况下执行耗时操作
3. 避免死锁:- 按固定顺序获取多个锁- 使用带超时的锁获取方法- 使用 tryLock() 方法避免死锁
4. 优先使用并发集合而不是同步集合
5. 考虑使用无锁数据结构和原子变量
6. 适当选择锁类型:- 简单场景:synchronized- 需要高级特性:ReentrantLock- 读多写少:ReadWriteLock- 高并发读场景:StampedLock
`);

各种锁的特点比较

锁类型可重入公平性选择阻塞超时等待可中断适用场景
synchronized简单同步场景
ReentrantLock需要高级特性的场景
ReadWriteLock读多写少场景
StampedLock部分高性能读多写少场景
Semaphore资源数量控制
CountDownLatch等待多个线程完成
CyclicBarrier多个线程相互等待
Phaser分阶段任务协调

希望这些示例和说明能帮助您理解Java中各种锁的使用方法和适用场景。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com