zoukankan      html  css  js  c++  java
  • 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
    ",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
    ", 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
    ",Thread.currentThread().getId(),count);
                    enough.await();
                }
                count--;
                System.out.printf("threadID:%s,reduce,count:%d
    ",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
    ", locktime);
                Thread.sleep(locktime);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                locker.unlock();
            }
        }
    
        private void printLockStatus() {
            System.out.printf("lock count:%d,queueLength:%d
    ", 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
  • 相关阅读:
    关于ArcGIS Server VS2010无法显示发布的地图服务
    NDK,动态链接库,JNI
    android开发中一些报错的解决方法
    查询死锁对象
    pb导入excel文件
    n_cst_ping在powerbuilder 11 中的变化,一面的程序可正常ping
    SQL拼音
    数据库优化
    android调用asp.net webservice,返回json结构
    iframe内部需要弹出浮层问题
  • 原文地址:https://www.cnblogs.com/lvjianwei/p/8442765.html
Copyright © 2011-2022 走看看