一、锁接口 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();
}
}
}
来源:https://www.cnblogs.com/haiyangwu/p/10443818.html