JDK5.0新特性系列---11.4线程 Condition

 

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

 

/**

 *有时候线程取得lock后需要在一定条件下才能做某些工作,比如经典的Producer和Consumer问题

 *在Java 5.0以前,这种功能是由Object类的wait(),notify()和notifyAll()等方法实现的

 *在5.0里面,这些功能集中到了Condition这个接口实现

 */

/**

 * 使用Condition的关键技术点如下:

 * 1.通过Lock的newCondition方法创建Condition的对象

 * 2.Condition的await方法使当前线程进入等待状态,并且释放它占据的Lock,直到有其他的线程唤醒当前线程时,重新占有Lock.

 * 3.Condition的signal方法唤醒其他正在等待该Condition的线程.

 */

public class ConditionTest {

    /**

     * 篮子程序,这里为了简化问题,篮子中最多只能有一个苹果

     * Consumer必须在篮子里有苹果的时候才能吃苹果,否则它必须暂时放弃对篮子的锁定

     * 等到Producer往篮子里放了苹果后再去拿来吃。

     * 否则它也需要暂时解锁等Comsumer把苹果吃了才能往篮子里放苹果。

     */

    public static class Basket{

        //锁

        Lock lock = new ReentrantLock();

        //根据锁产生Condition对象

        Condition produced = lock.newCondition();

        Condition consumed  = lock.newCondition();

        //篮子里的苹果数,最多为1

        int num = 0;

        //生产苹果,往篮子里放

        public void produce() throws InterruptedException{

            //获得锁

            lock.lock();

            System.out.println("Producer get a lock...");

 

                     try{

                //判断是否满足生产条件

                while(num == 1){

                    //如果有苹果,则不生产,放弃锁,进入睡眠

                    //等待消费者消费

                    System.out.println("Producer sleep...");

                    consumed.await();

                    System.out.println("Producer awaked...");

                }

                //生产苹果

                Thread.sleep(500);

                System.out.println("Producer produced an Apple.");

                num = 1;

                //通知等待produced Condition的线程

                produced.signal();

            }finally{

                lock.unlock();

            }

        }

        //消费苹果,从篮子里取

        public void consume() throws InterruptedException{

            //获得锁

            lock.lock();

            System.out.println("Consumer get a lock...");

            try{

                //判断是否满足消费条件

                while(num == 0){

                    //如果没有苹果,无法消费,则放弃锁,进入睡眠

                    //等待生产者生产苹果

                    System.out.println("Consumer sleep...");

                    produced.await();

                    System.out.println("Consumer awaked...");

                }

                //吃苹果

                Thread.sleep(500);

                System.out.println("Consumer consumed an Apple.");

                num = 0;

                //发信号唤醒某个等待consumed Condition的线程

                            consumed.signal();

            } finally {

                lock.unlock();

            }

        }

    }

    //测试Basket程序

    public static void testBasket() throws Exception{

        final Basket basket = new Basket();

        //定义一个producer

        Runnable producer  = new Runnable(){

            public void run() {

                try{

                    basket.produce();

                }catch(InterruptedException ex){

                    ex.printStackTrace();

                }

            }           

        };

        //定义一个consumer

        Runnable consumer = new Runnable(){

            public void run(){

                try{

                    basket.consume();

                }catch(InterruptedException ex){

                    ex.printStackTrace();

                }

            }

        };

        //各生产3个consumer和producer

        ExecutorService service = Executors.newCachedThreadPool();

        for(int i = 0; i <3; i++){

            service.submit(producer);

        }

        for(int i = 0;i<3;i++){

            service.submit(consumer);

        }

        service.shutdown();

    }

    public static void main(String... args)throws Exception{

        ConditionTest.testBasket();

    }

}

 

 

 

时间: 2024-11-09 02:14:30

JDK5.0新特性系列---11.4线程 Condition的相关文章

JDK5.0新特性系列---11.6线程 BlockingQueue

  importjava.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;   /**     本例介绍一个特殊的队列:BlockingQueue,如果BlockQueue是空的,从BlockingQueue取东西的操作将会

JDK5.0新特性系列---11.3线程 锁Lock

  import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.Reent

JDK5.0新特性系列---11.1线程 Callable和Future

  import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future;   /**     从本节开始,主要介绍J2SE5.0与线程相关的新特性,新的线程类主要集中在java.util.concurrent 包中,本节实例将介绍如何使用java.uti

JDK5.0新特性系列---11.2线程 任务执行架构

  import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecu

JDK5.0新特性系列---11.5.1线程 同步装置之Semaphore

    import java.util.ArrayList; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;   /**

JDK5.0新特性系列---11.5.2线程 同步装置之CountDownLatch

    import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors; /** * CountDownLatch维护一个计数器,等待这个CountDownLatch的线程必须等到计数器为0时才可以继续. * 以下实例模拟服务器的启动,假设启动一个服务器需要初始化3个组件,当3个组件初始化完毕后,服务器才算成功启

JDK5.0新特性系列---11.5.4线程 同步装置之Exchanger

/**  * Exchanger让两个线程互换信息  * 实例模拟服务生和顾客,服务生往空杯子中倒水,顾客从装满水的杯子中喝水,然后互换杯子,服务生接着倒水,顾客接着喝水.  */ /**  * 使用Exchanger的关键技术点如下:  * 1.初始化Exchanger对象时,可以通过泛型指定杯子能交换的信息类型.如"new Exchanger<String>;"表示只能交换String类型的信息  * 2.Exchanger的exchange方法表示当前线程准备交换信息

JDK5.0新特性系列---目录

  JDK5.0新特性系列---目录   JDK5.0新特性系列---1.自动装箱和拆箱   JDK5.0新特性系列---2.新的for循环 JDK5.0新特性系列---3.枚举类型 JDK5.0新特性系列---4.静态导入 JDK5.0新特性系列---5.可变长参数Varargs JDK5.0新特性系列---6.格式化输出 JDK5.0新特性系列---7.使用ProcessBuilder执行本地命令 JDK5.0新特性系列---8.泛型编程 JDK5.0新特性系列---9.注释功能Annota

JDK5.0新特性系列---10.监控与管理虚拟机

  import java.lang.management.ClassLoadingMXBean; import java.lang.management.CompilationMXBean; import java.lang.management.GarbageCollectorMXBean; import java.lang.management.ManagementFactory; import java.lang.management.MemoryMXBean; import java.