并发编程 AQS 思想之Condition 接口 的标准使用(十三)

今天我们分析并发编程原子操作 AQS 思想之Condition 接口 的标准使用:

任意一个 Java 对象,都拥有一组监视器方法(定义在 java.lang.Object 上), 主要包括 wait()wait(long timeout)notify()以及 notifyAll()方法,这些方法与

synchronized 同步关键字配合,可以实现等待 / 通知模式。 Condition 接口也提供 了类似 Object 的监视器方法,与 Lock 配合可以实现等待 / 通知模式。
 
1、Condition 常用方法:
 
2、Condition 使用范式:
 
3、Condition 使用 配合Lock接口:
public class ExpressCond {
    public final static String CITY = "ShangHai";
    private int km;/*快递运输里程数*/
    private String site;/*快递到达地点*/

    private Lock kmLock = new ReentrantLock();//里程锁
    private Lock siteLock = new ReentrantLock();//地点锁,可以和里程锁用同意把锁。

    private Condition kmCond = kmLock.newCondition();//控制里程数的
    private Condition siteCond = siteLock.newCondition();//控制地点的
    public ExpressCond() {
    }
    public ExpressCond(int km, String site) {
        this.km = km;
        this.site = site;
    }
    /* 变化公里数,然后通知处于wait状态并需要处理公里数的线程进行业务处理*/
    public void changeKm(){
        kmLock.lock();
        try{
            this.km = 101;
            kmCond.signal();
            //kmCond.signalAll();
        }finally {
            kmLock.unlock();
        }  
    }

    /* 变化地点,然后通知处于wait状态并需要处理地点的线程进行业务处理*/
    public  void changeSite(){
    	siteLock.lock();
    	try {
    		this.site = "BeiJing";
    		siteCond.signal();//通知其他在锁上等待的线程
    	}finally {
    		siteLock.unlock();
    	}
    }

    /*当快递的里程数大于100时更新数据库*/
    public void waitKm(){
        kmLock.lock();
        try{
            while(this.km<100){
                try {
                    kmCond.await();
                    System.out.println("Check Site thread["
                            +Thread.currentThread().getId()
                            +"] is be notified");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }finally {
            kmLock.unlock();
        }
        System.out.println("the Km is "+this.km+",I will change db");
    }

    /*当快递到达目的地时通知用户*/
    public void waitSite(){
    	siteLock.lock();
    	try {
        	while(this.site.equals(CITY)) {
        		try {
    				siteCond.await();//当前线程进行等待
    				System.out.println("check Site thread["+Thread.currentThread().getName()
    						+"] is be notify");
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
        	}
    	}finally {
    		siteLock.unlock();
    	}
        System.out.println("the site is "+this.site+",I will call user");
    }
}

测试main方法:

public class TestCond {
    private static ExpressCond express = new ExpressCond(0,ExpressCond.CITY);
    /*检查里程数变化的线程,不满足条件,线程一直等待*/
    private static class CheckKm extends Thread{
        @Override
        public void run() {
        	express.waitKm();
        }
    }

    /*检查地点变化的线程,不满足条件,线程一直等待*/
    private static class CheckSite extends Thread{
        @Override
        public void run() {
        	express.waitSite();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        for(int i=0;i<3;i++){
            new CheckSite().start();
        }
        for(int i=0;i<3;i++){
            new CheckKm().start();
        }
        Thread.sleep(1000);
        express.changeKm();//快递里程变化
        express.changeSite();//快递地点变化
    }
}

执行结果:

 
4、了解 LockSupport:
LockSupport 定义了一组的公共静态方法,这些方法提供了最基本的线程阻 塞和唤醒功能,而 LockSupport 也成为构建同步组件的基础工具。 LockSupport 定义了一组以 park 开头的方法用来阻塞当前线程,以及 unpark(Thread thread)方法来唤醒一个被阻塞的线程。 LockSupport 增加了 park(Object blocker)、 parkNanos(Object blocker,long nanos) parkUntil(Object blocker,long deadline)3 个方法,用于实现阻塞当前线程的功能,其中参数 blocker 是用来标识当前线程在等待的对象(以下称为阻塞对象),该对象主要用于问题 排查和系统监控,此类用的不多,方法如下图:
 

有用到时可以认真测试,今天分享到此结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寅灯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值