Java Condition条件对象
Condition用于管理已经获得了一个锁但是却不能做有用工作的线程。由Lock对象的newCondition()方法一个与当前Lock对象相关联的条件对象,共同管理该锁相关的对象和线程。
当线程已经获得锁,但是因为条件限制,无法继续工作的时候,调用Condition.await()方法,此线程进入该条件对象的等待集。当锁可用时,该线程不能马上解除阻塞。相反,它处于阻塞状态,直到另个线程调用同一条件上的signalAll方法时为止,这个方法可以激活所有等待的线程。Condition还有一个Signal方法,该方法是随机激活一个线程。
SignalAll不会立即激活一个等待线程,它仅仅解除等待线程的阻塞,以便这些线程可以在当前线程退出同步方法之后,通过竞争实现对对象的访问。
/** * Created by LvJianwei on 2018/2/11. */ import java.util.Random; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; /** * @program: ConditionDemo * @description: * @author: LvJianwei * @create: 2018-02-11 15:57 **/ public class ConditionDemo { public static void main(String[] args) { ConditionDemo demo = new ConditionDemo(); Runnable rAdd = () -> { while (true) { try { demo.countAdd(); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }; Runnable rReduce = () -> { while (true) { try { demo.countReduce(); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }; for (int i = 0; i < 5; i++) { Thread t = new Thread(rReduce); t.start(); } for (int i = 0; i < 5; i++) { Thread t = new Thread(rAdd); t.start(); } } private Random random=new Random(System.currentTimeMillis()); private ReentrantLock locker = new ReentrantLock(); private Condition enough; private int count = 0; private int enoughCount=3; public ConditionDemo() { enough = locker.newCondition(); } public void caculateWithLock() { locker.lock(); try { int randomResult=random.nextInt(); boolean shouldWait=randomResult%5==0; System.out.printf("randomResult:%d%%5==0:%b,%s\n",randomResult,shouldWait,shouldWait?"await":"continue"); while(!shouldWait) { countAdd(); enough.await(); } countReduce(); printLockStatus(); longTimeLock(); System.out.println("final count:" + count); enough.signalAll(); } catch (InterruptedException e) { e.printStackTrace(); } finally { locker.unlock(); } } public void countAdd() { locker.lock(); try { count++; System.out.printf("Add,count:%d\n", count); if(count>enoughCount){ System.out.println("signAll"); enough.signalAll(); } } finally { locker.unlock(); } } public void countReduce() { System.out.println("countReduce start,threadID:"+Thread.currentThread().getId()); locker.lock(); try { while (count<enoughCount){ System.out.printf("threadID:%s,await,count:%d\n",Thread.currentThread().getId(),count); enough.await(); } count--; System.out.printf("threadID:%s,reduce,count:%d\n",Thread.currentThread().getId(),count); } catch (InterruptedException e) { e.printStackTrace(); } finally { locker.unlock(); } } public void longTimeLock() { locker.lock(); try { printLockStatus(); int locktime = 3000; System.out.printf("longTimeLock:%d ms\n", locktime); Thread.sleep(locktime); } catch (InterruptedException e) { e.printStackTrace(); } finally { locker.unlock(); } } private void printLockStatus() { System.out.printf("lock count:%d,queueLength:%d\n", locker.getHoldCount(), locker.getQueueLength()); } }
add和reduce方法分别关联5个线程,对于reduce方法,只有当count>=enoughCount时才会进行减操作,否则就等待,由add方法,当count>enoughCount时,触发signalall方法。
下面运行结果可以看出,开始的13、11、12线程启动后,发现count<enoughCount,进入阻塞状态,直到add方法增加count到大于enoughCount时才执行减操作。
countReduce start,threadID:13 threadID:13,await,count:0 countReduce start,threadID:11 threadID:11,await,count:0 Add,count:1 Add,count:2 countReduce start,threadID:12 threadID:12,await,count:2 Add,count:3 Add,count:4 signAll countReduce start,threadID:15 threadID:15,reduce,count:3 countReduce start,threadID:14 threadID:14,reduce,count:2
posted on 2018-02-11 17:31 Lv Jianwei 阅读(391) 评论(0) 编辑 收藏 举报