ReentrantLock、Condition
ReentrantLock是AQS提供的可重入锁,一般和Condition配合使用,达到对线程分组唤醒功能;Condition中的wait()和signal()方法等同Object的wait()和notify()方法;
1.ReentrantLock重入锁使用:
1.1 代码
package com.zl.concurrency.example.aqs.lock;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j public class ConditionExample { public static void main(String[] args) { ReentrantLock reentrantLock = new ReentrantLock(); //一个ReentrantLock可以实例多个condition,通过对不同的condition的wait和signal实现对不同线程的等待和唤醒 Condition condition = reentrantLock.newCondition(); Thread a = new Thread(()->{ try { reentrantLock.lock(); log.info("wait signal"); condition.await();//调用await方法后,该线程将释放该锁,并且处于阻塞状态 } catch (InterruptedException e) { e.printStackTrace(); } log.info("get signal"); reentrantLock.unlock(); });
a.start(); Thread b = new Thread(()->{ reentrantLock.lock(); log.info("get lock"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } condition.signalAll(); log.info("send signal -"); reentrantLock.unlock(); });
b.start(); } }
1.2运行结果:
14:59:10.266 [Thread-0] INFO com.zl.concurrency.example.aqs.lock.ConditionExample - wait signal 14:59:10.272 [Thread-1] INFO com.zl.concurrency.example.aqs.lock.ConditionExample - get lock 14:59:13.273 [Thread-1] INFO com.zl.concurrency.example.aqs.lock.ConditionExample - send signal - 14:59:13.273 [Thread-0] INFO com.zl.concurrency.example.aqs.lock.ConditionExample - get signal
1.3结果分析
可以看到执行顺序是:a线程启动,拿到reentrantLock锁,锁定之后,通过condition调用awit()方法阻塞线程同时awit()方法会自动释放ReentrantLock锁,然后b线程启动,拿到rentrantLock锁后睡眠3s后,在通过condition唤醒该condition阻塞的所有锁;a线程被唤醒后打印;
ReentrantLock(可重入锁)与synchronized区别
可重入性:都可以重入
性能的区别:更建议使用synchronized
功能方面区别:
ReentrantLock的独有功能:
1.可指定是公平锁还是非公平锁
2.提供了一个Condition类,可以分组唤醒需要唤醒的线程
3.提供了能够中断等待锁的线程的机制,lock.lockInterruptibly()
我们曾如此渴望生命的波澜,到后来才发现,人生最曼妙的风景是内心的淡定与从容