多线程(十一,aq原理reentrantlock的条件队列条件)

  

1,条件介绍

  

1.1条件是对线程的等待,通知的增强

  

1.2在ReentrantLock中他的实现类是aq中的ConditionObject,实现了条件接口,利用aq的节点,实现了条件队列。

  

多线程(十一,aq原理reentrantlock的条件队列条件)

  

多线程(十一,aq原理reentrantlock的条件队列条件)

  

多线程(十一,aq原理reentrantlock的条件队列条件)

  

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运行结果

  

多线程(十一,aq原理reentrantlock的条件队列条件)

  

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);
  } 
  

3.1.1等待()方法会释放当前线程持有的锁,就是fullyRelease方法的作用

多线程(十一,aq原理reentrantlock的条件队列条件)