线程之Condition通信

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConditionCommunication {

    /**
     * 这一个示例的学习应该和传统的线程通信相互对比,Condition的通信优点查看文档
     */
    public static void main(String[] args) {

        final Bussiness bussiness = new Bussiness();
        
        new Thread(new Runnable(){
            public void run() {
                for(int i=0;i<50;i++){
                    try {
                        bussiness.child();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
        
        for(int i=0;i<50;i++){
            try {
                bussiness.main();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    
    
    /*
     * 要上在要操作资源的内部方法上,而不是线程上
     * 如果Bussiness的方法锁在线程上那么如果另外的对象再次调用时还要加锁
     * 
     * 要用到的共同数据(包括同步锁)的若干方法应归在同一个类的身上,这种设计体现了高类聚和程序的健壮性
     */
    static class Bussiness{
        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
        //设置该那个线程运行
        boolean isRun = true;
        void child() throws InterruptedException{
            lock.lock();
            try{
                //这里的判断最好是使用while,提防假唤醒
                while(!isRun){
                    //不该当前线程运行,就调用wait
                    //this.wait();这里不能用
                    condition.await();
                }
                for(int i=0;i<10;i++){
                    System.out.println("child is running the "+(i+1)+" times ");
                }
                //改变值
                isRun = false;
                //把另一个线程唤醒
                //this.notify();这里不能用
                condition.signal();
            }finally{
                lock.unlock();
            }
            
                
        }
        
        void main() throws InterruptedException{
            lock.lock();
            try{
                //这里的判断最好是使用while,提防假唤醒
                while(isRun){
                    //不该当前线程运行,就调用wait
                    //this.wait();
                    condition.await();
                }
                    for(int i=0;i<100;i++){
                        System.out.println("main is running the "+(i+1)+" times");
                    }
                    //改变值
                    isRun = true;
                    //把另一个线程唤醒
                    //this.notify();
                    condition.signal();
            }finally{
                lock.unlock();
            }
            
        }
    }
}

 

posted @ 2014-03-16 00:01  huidaoli  阅读(158)  评论(0编辑  收藏  举报