本文目录导读:

我将为您展示一个完整的Java可重入锁(ReentrantLock)案例,包含基本用法和高级特性。
基础可重入锁案例
import java.util.concurrent.locks.ReentrantLock;
public class BasicReentrantLockDemo {
private final ReentrantLock lock = new ReentrantLock();
private int count = 0;
// 基本加锁和解锁
public void increment() {
lock.lock();
try {
count++;
System.out.println(Thread.currentThread().getName() + " - count: " + count);
} finally {
lock.unlock();
}
}
// 可重入性演示:同一个线程可以多次获取锁
public void reentrantMethod() {
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + " - 第一次获取锁");
// 再次获取同一把锁
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + " - 第二次获取锁(重入)");
} finally {
lock.unlock();
}
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
BasicReentrantLockDemo demo = new BasicReentrantLockDemo();
// 演示可重入性
demo.reentrantMethod();
// 多线程竞争
Runnable task = () -> {
for (int i = 0; i < 3; i++) {
demo.increment();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t1 = new Thread(task, "Thread-1");
Thread t2 = new Thread(task, "Thread-2");
t1.start();
t2.start();
}
}
高级特性案例
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class AdvancedReentrantLockDemo {
private final ReentrantLock fairLock = new ReentrantLock(true); // 公平锁
private final ReentrantLock unfairLock = new ReentrantLock(); // 非公平锁(默认)
// 可中断锁
public void interruptibleLock() throws InterruptedException {
ReentrantLock lock = new ReentrantLock();
Thread t1 = new Thread(() -> {
lock.lock();
try {
System.out.println("Thread-1 获取锁,正在执行...");
Thread.sleep(5000); // 模拟长时间任务
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
System.out.println("Thread-1 释放锁");
}
});
Thread t2 = new Thread(() -> {
try {
System.out.println("Thread-2 尝试获取锁(可中断)");
lock.lockInterruptibly();
try {
System.out.println("Thread-2 成功获取锁");
} finally {
lock.unlock();
}
} catch (InterruptedException e) {
System.out.println("Thread-2 被中断");
}
});
t1.start();
Thread.sleep(100);
t2.start();
Thread.sleep(100);
// 中断 t2
t2.interrupt();
}
// 尝试获取锁(非阻塞)
public void tryLockDemo() {
ReentrantLock lock = new ReentrantLock();
// 尝试获取锁,如果获取不到立即返回
if (lock.tryLock()) {
try {
System.out.println("成功获取锁");
// 执行任务
} finally {
lock.unlock();
}
} else {
System.out.println("锁被其他线程持有");
}
// 尝试获取锁,等待指定时间
try {
if (lock.tryLock(3, TimeUnit.SECONDS)) {
try {
System.out.println("在3秒内成功获取锁");
} finally {
lock.unlock();
}
} else {
System.out.println("3秒内未获取到锁");
}
} catch (InterruptedException e) {
System.out.println("获取锁时被中断");
}
}
// 公平锁与非公平锁对比
public void fairLockDemo() {
Runnable task = () -> {
for (int i = 0; i < 3; i++) {
fairLock.lock();
try {
System.out.println(Thread.currentThread().getName() + " 获取公平锁");
} finally {
fairLock.unlock();
}
unfairLock.lock();
try {
System.out.println(Thread.currentThread().getName() + " 获取非公平锁");
} finally {
unfairLock.unlock();
}
}
};
Thread[] threads = new Thread[5];
for (int i = 0; i < 5; i++) {
threads[i] = new Thread(task, "Thread-" + (i + 1));
threads[i].start();
}
}
public static void main(String[] args) throws InterruptedException {
AdvancedReentrantLockDemo demo = new AdvancedReentrantLockDemo();
System.out.println("=== 可中断锁演示 ===");
demo.interruptibleLock();
Thread.sleep(6000);
System.out.println("\n=== 尝试获取锁演示 ===");
demo.tryLockDemo();
System.out.println("\n=== 公平锁与非公平锁演示 ===");
demo.fairLockDemo();
}
}
生产者消费者案例
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ProducerConsumerDemo {
private final ReentrantLock lock = new ReentrantLock();
private final Condition notEmpty = lock.newCondition();
private final Condition notFull = lock.newCondition();
private final Queue<Integer> queue = new LinkedList<>();
private final int MAX_SIZE = 5;
private int count = 0;
// 生产者
public void produce() {
lock.lock();
try {
while (queue.size() == MAX_SIZE) {
System.out.println("队列已满,生产者等待...");
notFull.await(); // 等待队列不满
}
int value = ++count;
queue.offer(value);
System.out.println(Thread.currentThread().getName() + " 生产: " + value);
notEmpty.signal(); // 通知消费者可以消费了
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
// 消费者
public void consume() {
lock.lock();
try {
while (queue.isEmpty()) {
System.out.println("队列为空,消费者等待...");
notEmpty.await(); // 等待队列不空
}
int value = queue.poll();
System.out.println(Thread.currentThread().getName() + " 消费: " + value);
notFull.signal(); // 通知生产者可以生产了
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
ProducerConsumerDemo demo = new ProducerConsumerDemo();
// 启动生产者线程
Runnable producerTask = () -> {
for (int i = 0; i < 10; i++) {
demo.produce();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
// 启动消费者线程
Runnable consumerTask = () -> {
for (int i = 0; i < 10; i++) {
demo.consume();
try {
Thread.sleep(150);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread producer1 = new Thread(producerTask, "Producer-1");
Thread producer2 = new Thread(producerTask, "Producer-2");
Thread consumer1 = new Thread(consumerTask, "Consumer-1");
Thread consumer2 = new Thread(consumerTask, "Consumer-2");
producer1.start();
producer2.start();
consumer1.start();
consumer2.start();
}
}
锁超时与中断处理案例
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class LockTimeoutDemo {
private final ReentrantLock lock = new ReentrantLock();
public void performTask() {
try {
// 尝试获取锁,最多等待2秒
if (lock.tryLock(2, TimeUnit.SECONDS)) {
try {
System.out.println(Thread.currentThread().getName() + " 获取锁成功");
Thread.sleep(3000); // 模拟长时间任务
} finally {
lock.unlock();
System.out.println(Thread.currentThread().getName() + " 释放锁");
}
} else {
System.out.println(Thread.currentThread().getName() + " 等待超时,放弃执行");
}
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " 被中断");
}
}
public static void main(String[] args) throws InterruptedException {
LockTimeoutDemo demo = new LockTimeoutDemo();
// 线程1获取锁并执行任务
Thread t1 = new Thread(() -> demo.performTask(), "Thread-1");
// 线程2尝试获取锁
Thread t2 = new Thread(() -> demo.performTask(), "Thread-2");
t1.start();
Thread.sleep(100); // 确保Thread-1先获取锁
t2.start();
}
}
- 可重入性:同一个线程可以多次获取同一把锁
- 公平性:可以指定公平锁(先来先服务)或非公平锁
- 可中断:支持中断等待中的线程
- 超时机制:支持tryLock带超时时间
- 条件变量:通过Condition实现复杂的线程同步
注意事项
- 使用
lock()后一定要在finally中释放锁 - 优先使用
tryLock()避免死锁 - 根据场景选择合适的锁类型(公平/非公平)
- 合理使用中断处理,保持线程的可响应性
这些案例涵盖了ReentrantLock的主要使用场景,可以根据实际需求选择合适的实现方式。