【4】锁超时尝试
@Slf4jpublic class ReentrantLockDemo {public static void main(String[] args) throws InterruptedException {ReentrantLock lock = new ReentrantLock();Thread t1 = new Thread(() -> {log.debug("t1启动...");//超时try {// 注意: 即使是设置的公平锁,此方法也会立即返回获取锁成功或失败,公平策略不生效if (!lock.tryLock(1, TimeUnit.SECONDS)) {log.debug("等待 1s 后获取锁失败,返回");return;}} catch (InterruptedException e) {e.printStackTrace();return;}try {log.debug("t1获得了锁");} finally {lock.unlock();}}, "t1");lock.lock();try {log.debug("main线程获得了锁");t1.start();//先让线程t1执行Thread.sleep(2000);} finally {lock.unlock();}}}【5】条件变量的尝试
说明:
1)java.util.concurrent类库中提供Condition类来实现线程之间的协调 。调用Condition.await() 方法使线程等待,其他线程调用Condition.signal() 或 Condition.signalAll() 方法唤醒等待的线程 。
2)由于可控的原因我们甚至可以多个条件队列来进行对线程调控 。
注意:调用Condition的await()和signal()方法,都必须在lock保护之内 。
@Slf4jpublic class ReentrantLockDemo {private static ReentrantLock lock = new ReentrantLock();private static Condition cigCon = lock.newCondition();private static Condition takeCon = lock.newCondition();private static boolean hashcig = false;private static boolean hastakeout = false;//送烟public void cigratee(){lock.lock();try {while(!hashcig){try {log.debug("没有烟,歇一会");cigCon.await();}catch (Exception e){e.printStackTrace();}}log.debug("有烟了,干活");}finally {lock.unlock();}}//送外卖public void takeout(){lock.lock();try {while(!hastakeout){try {log.debug("没有饭,歇一会");takeCon.await();}catch (Exception e){e.printStackTrace();}}log.debug("有饭了,干活");}finally {lock.unlock();}}public static void main(String[] args) {ReentrantLockDemo6 test = new ReentrantLockDemo6();new Thread(() ->{test.cigratee();}).start();new Thread(() -> {test.takeout();}).start();new Thread(() ->{lock.lock();try {hashcig = true;log.debug("唤醒送烟的等待线程");cigCon.signal();}finally {lock.unlock();}},"t1").start();new Thread(() ->{lock.lock();try {hastakeout = true;log.debug("唤醒送饭的等待线程");takeCon.signal();}finally {lock.unlock();}},"t2").start();}}ReentrantLock源码分析(版本为jdk14)【0】前置部分最好有关于JDK实现管程的了解【可查看 深入理解AQS--jdk层面管程实现】
【1】ReentrantLock类自身部分
0)继承关系
//锁的接口定义,定义了一个锁该具备哪一些功能public interface Lock {void lock();void lockInterruptibly() throws InterruptedException;boolean tryLock();boolean tryLock(long time, TimeUnit unit) throws InterruptedException;void unlock();Condition newCondition();}1)属性值
//同步器句柄,同步器提供了所有的实现机制private final Sync sync;2)构造方法
//默认是采用非公平的同步器public ReentrantLock() {sync = new NonfairSync();}//此外可以根据传入的参数选择同步器public ReentrantLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync();}3)其他方法【看完之后,你会发现,其实ReentrantLock什么事都不干,统统都交给了持有的AQS同步器去干活了,有一种修饰器设计模式的味道,只是包装了一下,具体内部的同步器类型由自己选择,所以同步器显得就很重要】
public class ReentrantLock implements Lock, java.io.Serializable {.....//获取锁定public void lock() {sync.lock();}//中断式的加锁,如果没有被中断就会加锁public void lockInterruptibly() throws InterruptedException {sync.lockInterruptibly();}//仅当在调用时锁不被另一个线程持有时才获取锁public boolean tryLock() {return sync.tryLock();}//超时加锁,限定加锁时间public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {return sync.tryLockNanos(unit.toNanos(timeout));}//尝试释放此锁public void unlock() {sync.release(1);}//返回一个用于此锁定实例的条件实例,说白了就是监视器public Condition newCondition() {return sync.newCondition();}//查询当前线程在此锁上保留的数量public int getHoldCount() {return sync.getHoldCount();}public boolean isHeldByCurrentThread() {return sync.isHeldExclusively();}//判断同步器是否在被持有状态,也就是被加锁了public boolean isLocked() {return sync.isLocked();}//判断同步器的类型public final boolean isFair() {return sync instanceof FairSync;}protected Thread getOwner() {return sync.getOwner();}public final boolean hasQueuedThreads() {return sync.hasQueuedThreads();}//判断同步器里面是否有该线程public final boolean hasQueuedThread(Thread thread) {return sync.isQueued(thread);}public final int getQueueLength() {return sync.getQueueLength();}protected Collection<Thread> getQueuedThreads() {return sync.getQueuedThreads();}public boolean hasWaiters(Condition condition) {if (condition == null)throw new NullPointerException();if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))throw new IllegalArgumentException("not owner");return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);}//返回条件队列里面等待的线程的个数public int getWaitQueueLength(Condition condition) {if (condition == null)throw new NullPointerException();if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))throw new IllegalArgumentException("not owner");return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);}//返回条件队列里面等待的线程protected Collection<Thread> getWaitingThreads(Condition condition) {if (condition == null)throw new NullPointerException();if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))throw new IllegalArgumentException("not owner");return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);}}
经验总结扩展阅读
- Spring 深入——IoC 容器 02
- 五行缺木男和五行缺土女 婚姻不稳需多理解
- 属龙人和属蛇的缘份发展趋势 需多理解包容之心
- 属猴人和属狗感情甜蜜顺利 互相理解则爱情旺
- 饿火命和饿木命合作生意 事业旺盛多理解
- 基于PL022 SPI 控制器 海思3516系列芯片SPI速率慢问题深入分析与优化
- 缺水男适合的配对 相互包容与理解
- 壬水女和癸水男契合度高 互相理解包容
- 深入人心的惊艳签名 文艺且暖心的签名
- 深入剖析Sgementation fault原理