1,条件介绍
1.1条件是对线程的等待,通知的增强
1.2在ReentrantLock中他的实现类是aq中的ConditionObject,实现了条件接口,利用aq的节点,实现了条件队列。
2,案例分析
2.1说明:线程1获取锁,然后等待,释放锁,线程2获得锁,唤醒线程1,释放锁,线程1重新获取锁,释放锁。
2.2代码
2.2.1线程1
<代码>进口java.util.concurrent.locks.Condition; 进口java.util.concurrent.locks.ReentrantLock; 公共类Task1实现Runnable { 私人ReentrantLock锁; 反对私人条件; 公共Task1 (ReentrantLock锁、条件con) { 这一点。锁=锁; 这一点。反对=反对; } @Override 公共空间run () { 尝试{ lock.lock (); System.out.println (Thread.currentThread () . getname() +”获取到锁....”); System.out.println (Thread.currentThread () . getname() +”开始阻塞....”); con.await (); System.out.println (Thread.currentThread () . getname() +”重新获取锁,继续执行....”); thread . sleep (2000); }捕捉(InterruptedException e) { e.printStackTrace (); 最后}{ System.out.println (Thread.currentThread () . getname() +”释放锁....”); lock.unlock (); } } } 代码>2.2.2
线程2
<代码>进口java.util.concurrent.locks.Condition; 进口java.util.concurrent.locks.ReentrantLock; 公开课Task2实现Runnable { 私人ReentrantLock锁; 反对私人条件; 公共Task2 (ReentrantLock锁、条件con) { 这一点。锁=锁; 这一点。反对=反对; } @Override 公共空间run () { 尝试{ lock.lock (); System.out.println (Thread.currentThread () . getname() +”获取到锁....”); System.out.println (Thread.currentThread () . getname() +”唤醒线程1 ....”); con.signal (); thread . sleep (2000); }捕捉(InterruptedException e) { e.printStackTrace (); 最后}{ System.out.println (Thread.currentThread () . getname() +”释放锁....”); lock.unlock (); } } } 代码>
2.2.3启动文件
<代码>进口java.text.ParseException; 进口java.util.concurrent.locks.Condition; 进口java.util.concurrent.locks.ReentrantLock; 公开课主要{ 公共静态void main (String [] args)抛出ParseException, InterruptedException { ReentrantLock锁=新的ReentrantLock(真正的); 条件条件=lock.newCondition (); 线程t1=新线程(新Task1(锁、条件),“线程1”); thread . sleep (2000); 线程t2=新线程(新Task2(锁、条件),线程2); t1.start (); t2.start (); } } 代码>
2.2.4运行结果
3,源码分析
3.1获取锁的源码在上一篇已经分析过了,来看等待操作:
<代码>公共最后空白等待()抛出InterruptedException { 如果(Thread.interrupted ()) 抛出InterruptedException ();//判断线程是否中断,中断则抛出异常 节点的节点=addConditionWaiter ();//当前线程包装节点,放入【条件对列】,注意不是【等待队列】 int savedState=fullyRelease(节点);//释放锁资源 int interruptMode=0; 而(! isOnSyncQueue(节点)){//如果当前节点不在【等待队列】 LockSupport.park(这个);//在这里阻塞等,待被唤,醒后面代码唤醒前不执行 如果((interruptMode=checkInterruptWhileWaiting(节点))!=0) 打破; } 如果(acquireQueued(节点,savedState),,interruptMode !=THROW_IE) interruptMode=重新中断; 如果节点。nextWaiter !=null)//清理如果取消 unlinkCancelledWaiters (); 如果(interruptMode !=0) reportInterruptAfterWait (interruptMode); }代码>