一、锁接口 Lock,ReadWriteLock:
1、Lock,实现类有ReentractLock、WriteLock、ReadLock;
2、ReadWriteLock,主要实现类是ReentrantReadWriteLock,有两个方法 writeLock()、readLock() ,返回值是 WriteLock,ReadLock,这两类继承与Lock接口;
3、常用方法:
lock() / unlock():获取/释放锁,lock()会阻塞直到成功
lockInterruptibly():与lock() 不同的是它可以响应中断,如果被其他线程中断了,则抛出InterruptedException
tryLock() / tyrLock(long time, TimeUnit unit):只是尝试获取锁,立即返回,返回值为 boolean。无参数不阻塞,有参数会根据设置的时间阻塞等待,如果发生中断抛出InterruptedException
newCondition:新建一个条件,一个lock可以关联多个条件
二、对比 ReentractLock 和 synchornized:
相比synchronized,ReentractLock可以实现与synchronized 相同的语义,而且支持以非阻塞方法获取锁,可以响应中断,可以限时,更为灵活。不过,synchronized 的使用更为简单,写的代码更少,也不容易出错。
三、Condition:
锁用于解决竞态条件问题,条件是线程间的协作机制。显示锁与synchronized 相对应,而显式条件与wait/notify 相对应。wait/notify 与synchronized 配合使用,显式条件与显示锁配合使用。
1、声明:Condition c = reentractLock.newCondition();
2、常用方法:
await() / signal():等待/通知,使用时需获取锁,await() 发生中断,抛出 InterruptedException,但中断标志位会被清空。awaitUniterruptibly() 不响应中断
四、ReentractLock、Condition 搭配使用:
/*** ReentrantLock 显式锁** Condition 显式条件** 生产者、消费者协作模式*/public class ReentrantLockTest {private int e = 1;private int num = 30;//private BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(num);private Queue<Integer> queue = new ArrayDeque<>(num);private Lock lock = new ReentrantLock();private Condition queueFull = lock.newCondition();private Condition queueEmpty = lock.newCondition();public static void main(String[] args) throws InterruptedException {ReentrantLockTest reentrantLockTest = new ReentrantLockTest();for(int i = 0; i < reentrantLockTest.num; i++){new Thread(() -> {try {reentrantLockTest.producer();Thread.sleep((int)(Math.random() * 100));} catch (InterruptedException e1) {e1.printStackTrace();}}).start();}for(int i = 0; i < reentrantLockTest.num; i++){new Thread(() -> {try {reentrantLockTest.consumer();Thread.sleep((int)(Math.random() * 100));} catch (InterruptedException e1) {e1.printStackTrace();}}).start();}}public void producer() throws InterruptedException {lock.lockInterruptibly();try{while (queue.size() == num){queueFull.await();}queue.add(e++);System.out.println("producer" + Arrays.toString(queue.toArray()));queueEmpty.signal();}finally {lock.unlock();}}public void consumer() throws InterruptedException {lock.lockInterruptibly();try{while (queue.isEmpty()){queueEmpty.await();}System.out.println("poll:" + queue.poll() + ",comsumer" + Arrays.toString(queue.toArray()));queueFull.signal();}finally {lock.unlock();}}}