版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_37378518/article/details/85994221
使用ReentrantLock类
Lock lock = new ReentrantLock();
lock.lock();
//同步的代码段
...
lock.unlock();
Condition用法:await(), signal()方法调用之前需要调用lock.lock()获得同步监视器
Lock lock = new ReentrantLock();
Condition condition = new lock.newCondition();
try{
lock.lock();
...
condition.await();
} catch (...) {
...
} finally {
lock.unlock();
}
try{
lock.lock();
...
condition.signal();
} finally {
lock.unlock();
}
使用Condition实现通知部分线程
Lock lock = new ReentrantLock();
Condition conditionA = new lock.newCondition();
Condition conditionB = new lock.newCondition();
//唤醒所有被conditionA.await()等待的线程
conditionA.await(); --> conditionA.signalAll();
//唤醒所有被conditionB.await()等待的线程
conditionB.await(); --> conditionB.signalAll()
使用Lock与Condition模拟生产者与消费者
class Service {
private Lock lock = new ReentrantLock();
//生产者与消费者使用两个Condition对象
private Condition conditionPro = lock.newCondition();
private Condition conditionCon = lock.newCondition();
private int count = 0;
public void produce() {
try {
//获取锁
lock.lock();
//循环生成
while (true) {
//使用while循环判断count值
while (count > 5) {
//使生产者等待
conditionPro.await();
}
/*
* // 不能使用 if 对 count 值进行判断
* if (count > 5){
* conditionPro.await();
* }
* //使用if后,该生产者会暂时被等待,但可能被其它线程通知
* //然后,会继续执行对count的操作
*/
//此处count最大值可达到6
count++;
System.out.println("produce---" + count);
//生产者产生一个值后,count值此时一定 >= 1,可通知消费者
conditionCon.signalAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//释放锁
lock.unlock();
}
}
public void consume() {
try {
lock.lock();
while (true) {
while (count < 1) {
conditionCon.await();
}
count--;
System.out.println("consume---" + count);
conditionPro.signalAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
class Producer extends Thread {
private Service service;
Producer(Service service) {
this.service = service;
}
@Override
public void run() {
service.produce();
}
}
class Consumer extends Thread {
private Service service;
Consumer(Service service) {
this.service = service;
}
@Override
public void run() {
service.consume();
}
}
公平锁:获取锁的顺序是按照线程加锁的顺序来分配,即FIFO
非公平锁:随机获得锁,该方式可能造成某些线程一直拿不到锁,结果也就是不公平的了
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
读写锁ReentrantReadWriteLock的使用
该锁有两个锁,一个是读操作相关的锁,也称共享锁;一个是写操作相关的锁,也叫排他锁。
多个读锁间不互斥,读锁与写锁互斥,写锁与写锁互斥。
多个线程可以同时进行读操作,但同一时刻只允许一个线程进行写操作
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
lock.readLock().lock();
...
lock.readLock().lock();