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() {
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。