Java ReentrantLock
个人认为的好处主要在于用condition(await,signal)代替了synchronized的(wait,notify)
synchronized的(wait,notify)唤醒线程只能所有都唤醒或者唤醒随机一个
condition(await,signal)唤醒线程可以唤醒想要唤醒的线程类型
还有两个
指定公平锁还是非公平锁,默认非公平锁
提供lock().lockInterruptibly()实现中断等待锁的线程的机制(不太理解,日后补上)
看代码
package service; import java.util.ArrayList; import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class Product{ public int id = 0; public Product(int id) { this.id = id; } } class Producer extends Thread{ private TestReentrantLock tsetReentrantLock; private int id = 0; public Producer(TestReentrantLock tsetReentrantLock) { this.tsetReentrantLock = tsetReentrantLock; } @Override public void run() { for (int i = 0; i < 50; i++) { Product product = new Product(id++); this.tsetReentrantLock.put(product); } } } class Consumer extends Thread{ private TestReentrantLock testReentrantLock; public Consumer(TestReentrantLock testReentrantLock) { this.testReentrantLock = testReentrantLock; } @Override public void run() { for (int i = 0; i < 50; i++) { this.testReentrantLock.get(); } } } class TestReentrantLock{ private final int MAX = 10; private int count = 0; LinkedList<Product> list = new LinkedList<>(); private Lock lock = new ReentrantLock(); private Condition producer = lock.newCondition(); private Condition consumer = lock.newCondition(); public int getCount() { return count; } public void put(Product product) { lock.lock(); while(list.size() >= MAX) { System.out.println(Thread.currentThread().getName() + "队列已满,生产者等待中"); try { producer.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } consumer.signalAll(); count++; System.out.println(Thread.currentThread().getName() + "生产" + product.id + "ing" + "队列已使用" + count + "/10"); list.add(product); lock.unlock(); } public void get() { lock.lock(); while(list.size() == 0) { System.out.println(Thread.currentThread().getName() + "队列已空,消费者等待中"); try { consumer.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } producer.signalAll(); count--; Product product = list.removeFirst(); System.out.println(Thread.currentThread().getName() + "消费" + product.id + "ing" + "队列已使用" + count + "/10"); lock.unlock(); } } public class ReentrantLockTest { public static void main(String[] args) { TestReentrantLock testReentrantLock = new TestReentrantLock(); Producer producer = new Producer(testReentrantLock); Consumer consumer = new Consumer(testReentrantLock); producer.start(); consumer.start(); } }
我将condition分为生产者和消费者,condition精准唤醒效率更高,不会出现synchronized一起唤醒生产者和消费者导致的阻塞