• 条件阻塞Condition的应用


    复制代码
      1 import java.util.Random;
      2 import java.util.concurrent.ExecutorService;
      3 import java.util.concurrent.Executors;
      4 import java.util.concurrent.locks.Condition;
      5 import java.util.concurrent.locks.Lock;
      6 import java.util.concurrent.locks.ReentrantLock;
      7  
      8 /**
      9  * 有时候线程取得lock后需要在一定条件下才能做某些工作,比如说经典的Producer和Consumer问题。 在Java
     10  * 5.0以前,这种功能是由Object类的wait(), notify()和notifyAll()等方法实现的,
     11  * 在5.0里面,这些功能集中到了Condition这个接口来实现。
     12  */
     13 public class ConditionTest {
     14  
     15         /**
     16         * 篮子程序。Consumer必须在篮子里有苹果的时候才能吃苹果,否则它必须暂时放弃对篮子的锁定,
     17         * 等到Producer往篮子里放了苹果后再去拿来吃。而Producer必须等到篮子空了才能往里放苹果,
     18         * 否则它也需要暂时解锁等Consumer把苹果吃了才能往篮子里放苹果。
     19         */
     20         public static class Basket {
     21                // 锁
     22               Lock lock = new ReentrantLock();
     23                // 根据锁产生Condition对象
     24               Condition produced = lock .newCondition();
     25               Condition consumed = lock .newCondition();
     26                // 篮子中的苹果数
     27                int num = 0;
     28                // 篮子中的最多放的苹果数
     29                int count = 5;
     30  
     31                /**
     32                * 生产苹果,往篮子里放
     33                *
     34                * @throws InterruptedException
     35                */
     36                public void produce() throws InterruptedException {
     37                       // 获得锁
     38                       lock.lock();
     39                      System. out.println("Producer get a lock..." );
     40                       try {
     41                             // 判断是否满足生产条件
     42                             while (num == count) {
     43                                    // 如果有苹果,则不生产,放弃锁,进入睡眠
     44                                    // 等待消费者消费
     45                                   System. out.println("Producer sleep..." );
     46                                    consumed.await();
     47                                   System. out.println("Producer awaked..." );
     48                            }
     49                             /* 生产苹果 */
     50                            Thread. sleep(new Random().nextInt(50));
     51                            System. out.println("Producer produced an Apple." );
     52                             num++;
     53                            System. out.println("Producer 篮子里有" + num + "个苹果" );
     54                             // 通知等待produced Condition的线程
     55                             produced.signal();
     56                      } finally {
     57                             lock.unlock();
     58                      }
     59               }
     60  
     61                /**
     62                * 消费苹果,从篮子中取
     63                *
     64                * @throws InterruptedException
     65                */
     66                public void consume() throws InterruptedException {
     67                       // 获得锁
     68                       lock.lock();
     69                      System. out.println("Consumer get a lock..." );
     70                       try {
     71                             // 判断是否满足消费条件
     72                             while (num == 0) {
     73                                    // 如果没有苹果,无法消费,则放弃锁,进入睡眠
     74                                    // 等待生产者生产苹果
     75                                   System. out.println("Consumer sleep..." );
     76                                    produced.await();
     77                                   System. out.println("Consumer awaked..." );
     78                            }
     79                             /* 吃苹果 */
     80                            Thread. sleep(new Random().nextInt(500));
     81                            System. out.println("Consumer consumed an Apple." );
     82                             num--;
     83                            System. out.println("Consumer 篮子里剩" + num + "个苹果" );
     84                             // 发信号唤醒某个等待consumed Condition的线程
     85                             consumed.signal();
     86                      } finally {
     87                             lock.unlock();
     88                      }
     89               }
     90        }
     91  
     92         /**
     93         * 测试Basket程序
     94         */
     95         public static void testBasket() throws Exception {
     96                final Basket basket = new Basket();
     97                // 定义一个producer
     98               Runnable producer = new Runnable() {
     99                       public void run() {
    100                             try {
    101                                   basket.produce();
    102                            } catch (InterruptedException ex) {
    103                                   ex.printStackTrace();
    104                            }
    105                      }
    106               };
    107  
    108                // 定义一个consumer
    109               Runnable consumer = new Runnable() {
    110                       public void run() {
    111                             try {
    112                                   basket.consume();
    113                            } catch (InterruptedException ex) {
    114                                   ex.printStackTrace();
    115                            }
    116                      }
    117               };
    118  
    119                // 各产生10个consumer和producer
    120               ExecutorService service = Executors. newCachedThreadPool();
    121                for (int i = 0; i < 10; i++) {
    122                      service.execute(producer);
    123               }
    124                for (int i = 0; i < 10; i++) {
    125                      service.execute(consumer);
    126               }
    127               service.shutdown();
    128        }
    129  
    130         public static void main(String[] args) throws Exception {
    131               ConditionTest. testBasket();
    132        }
    133 }
    复制代码
  • 相关阅读:
    SEO 相关网站
    如何解决虚拟内存低问题呀?请高手指教!
    你读到第几句时心痛了?
    git的使用
    MySQL上手
    记一次在京东购买笔记本电脑的经历
    webpack入门
    Vuex笔记
    Python利用ConfigParser读取配置文件
    django学习之reverse方法
  • 原文地址:https://www.cnblogs.com/zhangyuhang3/p/6872662.html
Copyright © 2020-2023  润新知