ReentrantLock简介说明
下文笔者讲述"ReentrantLock简介",如下所示
ReentrantLock简介
`ReentrantLock`是Java中用于实现可重入锁的一个类
属于`java.util.concurrent.locks`包
ReentrantLock提供比`synchronized`关键字更灵活和强大的锁机制
===============================================================================
`ReentrantLock`是一个可重入的互斥锁
提供与`synchronized`关键字类似的功能
但具有更多的灵活性和功能
可重入性指同一个线程可以多次获取同一个锁而不会导致死锁
ReentrantLock主要特点
1.可重入性:
- 同一个线程可以多次获取同一个锁。
- 通过 `lock()` 方法获取锁
通过 `unlock()` 方法释放锁。
2. 公平性:
- 可以选择公平锁(Fair Lock)
或非公平锁(Non-Fair Lock)
- 公平锁:线程按照请求锁的顺序获取锁
- 非公平锁:线程可以插队获取锁,提高吞吐量
3. 条件变量:
- 支持多个条件变量(`Condition`),
可以更灵活地控制线程的等待和唤醒。
4. 定时锁:
- 支持尝试获取锁并在指定时间内等待锁的可用性。
5. 中断响应:
- 支持中断响应,
可以在等待锁的过程中响应中断。
ReentrantLock基本用法
1.获取和释放锁
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 {
lock.unlock();
}
}
public int getCount() {
lock.lock();
try {
return count;
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
ReentrantLockExample example = new ReentrantLockExample();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.increment();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.increment();
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Final count: " + example.getCount());
}
}
2.公平锁和非公平锁
import java.util.concurrent.locks.ReentrantLock;
public class FairLockExample {
private final ReentrantLock fairLock = new ReentrantLock(true); // 公平锁
private int count = 0;
public void increment() {
fairLock.lock();
try {
count++;
} finally {
fairLock.unlock();
}
}
public int getCount() {
fairLock.lock();
try {
return count;
} finally {
fairLock.unlock();
}
}
public static void main(String[] args) {
FairLockExample example = new FairLockExample();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.increment();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.increment();
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Final count: " + example.getCount());
}
}
3.使用条件变量
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionExample {
private final ReentrantLock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
private boolean isReady = false;
public void awaitReady() {
lock.lock();
try {
while (!isReady) {
condition.await();
}
System.out.println("Thread is ready to proceed.");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
public void setReady() {
lock.lock();
try {
isReady = true;
condition.signalAll();
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
ConditionExample example = new ConditionExample();
Thread t1 = new Thread(() -> {
example.awaitReady();
});
Thread t2 = new Thread(() -> {
example.awaitReady();
});
t1.start();
t2.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
example.setReady();
}
}
4.尝试获取锁
import java.util.concurrent.locks.ReentrantLock;
public class TryLockExample {
private final ReentrantLock lock = new ReentrantLock();
private int count = 0;
public void increment() {
if (lock.tryLock()) {
try {
count++;
System.out.println("Lock acquired by " + Thread.currentThread().getName());
} finally {
lock.unlock();
}
} else {
System.out.println("Lock not acquired by " + Thread.currentThread().getName());
}
}
public int getCount() {
lock.lock();
try {
return count;
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
TryLockExample example = new TryLockExample();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.increment();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.increment();
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Final count: " + example.getCount());
}
}
ReentrantLock优点
1.灵活性:
- 提供比`synchronized`更灵活锁机制
- 可以响应中断
支持定时锁
2.公平性:
- 可以选择公平锁或非公平锁
适用于不同的场景
3.条件变量:
- 支持多个条件变量
可以更灵活地控制线程的等待和唤醒。
4.可重入性:
- 同一个线程可以多次获取同一个锁
避免死锁。
ReentrantLock缺点
1.复杂性:
- 相比`synchronized`,`ReentrantLock`
使用更为复杂
需要手动管理锁的获取和释放。
2.性能开销:
- 相比 `synchronized`,`ReentrantLock`
可能会有一定的性能开销
尤其是在高并发场景下
例:使用ReentrantLock实现生产者-消费者模式
使用 `ReentrantLock` 和 `Condition` 实现生产者-消费者模式的示例 import java.util.Linkedlist; import java.util.Queue; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class ProducerConsumerExample { private final ReentrantLock lock = new ReentrantLock(); private final Condition notFull = lock.newCondition(); private final Condition notEmpty = lock.newCondition(); private final Queue<Integer> queue = new LinkedList<>(); private final int capacity = 10; public void produce(int item) { lock.lock(); try { while (queue.size() == capacity) { notFull.await(); } queue.add(item); System.out.println("Produced: " + item); notEmpty.signalAll(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { lock.unlock(); } } public int consume() { lock.lock(); try { while (queue.isEmpty()) { notEmpty.await(); } int item = queue.poll(); System.out.println("Consumed: " + item); notFull.signalAll(); return item; } catch (InterruptedException e) { Thread.currentThread().interrupt(); return -1; } finally { lock.unlock(); } } public static void main(String[] args) { ProducerConsumerExample example = new ProducerConsumerExample(); Thread producer = new Thread(() -> { for (int i = 0; i < 20; i++) { example.produce(i); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread consumer = new Thread(() -> { for (int i = 0; i < 20; i++) { example.consume(); try { Thread.sleep(150); } catch (InterruptedException e) { e.printStackTrace(); } } }); producer.start(); consumer.start(); } }
代码说明
1.定义锁和条件变量:
private final ReentrantLock lock = new ReentrantLock();
private final Condition notFull = lock.newCondition();
private final Condition notEmpty = lock.newCondition();
private final Queue<Integer> queue = new LinkedList<>();
private final int capacity = 10;
2.生产者方法:
public void produce(int item) {
lock.lock();
try {
while (queue.size() == capacity) {
notFull.await();
}
queue.add(item);
System.out.println("Produced: " + item);
notEmpty.signalAll();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
- 获取锁:`lock.lock()`
- 等待条件:如果队列已满,调用 `notFull.await()` 等待。
- 添加元素:将元素添加到队列中。
- 唤醒等待线程:调用 `notEmpty.signalAll()`
唤醒所有等待的消费者线程。
- 释放锁:`lock.unlock()`
3.消费者方法:
public int consume() {
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


