java线程并发blockingqueue类使用示例

 更新时间:2014年01月16日 09:52:09   作者:  
BlockingQueue是一种特殊的Queue,若BlockingQueue是空的,从BlockingQueue取东西的操作将会被阻断进入等待状态直到BlocingkQueue进了新货才会被唤醒,下面是用BlockingQueue来实现Producer和Consumer的例子


如果BlockingQueue是满的任何试图往里存东西的操作也会被阻断进入等待状态,直到BlockingQueue里有新的空间才会被唤醒继续操作。

BlockingQueue提供的方法主要有:

add(anObject): 把anObject加到BlockingQueue里,如果BlockingQueue可以容纳返回true,否则抛出IllegalStateException异常。
offer(anObject):把anObject加到BlockingQueue里,如果BlockingQueue可以容纳返回true,否则返回false。
put(anObject):把anObject加到BlockingQueue里,如果BlockingQueue没有空间,调用此方法的线程被阻断直到BlockingQueue里有新的空间再继续。
poll(time):取出BlockingQueue里排在首位的对象,若不能立即取出可等time参数规定的时间。取不到时返回null。
take():取出BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的对象被加入为止。

根据不同的需要BlockingQueue有4种具体实现:

(1)ArrayBlockingQueue:规定大小的BlockingQueue,其构造函数必须带一个int参数来指明其大小。其所含的对象是以FIFO(先入先出)顺序排序的。
(2)LinkedBlockingQueue:大小不定的BlockingQueue,若其构造函数带一个规定大小的参数,生成的BlockingQueue有大小限制,
若不带大小参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定。其所含的对象是以FIFO(先入先出)顺序排序的。
LinkedBlockingQueue和ArrayBlockingQueue比较起来,它们背后所用的数据结构不一样,
导致LinkedBlockingQueue的数据吞吐量要大于ArrayBlockingQueue,但在线程数量很大时其性能的可预见性低于ArrayBlockingQueue。
(3)PriorityBlockingQueue:类似于LinkedBlockingQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数所带的Comparator决定的顺序。
(4)SynchronousQueue:特殊的BlockingQueue,对其的操作必须是放和取交替完成的。

复制代码 代码如下:

package com.yao;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class BlockingQueueTest {

 /**
 定义装苹果的篮子
  */
 public static class Basket{
  // 篮子,能够容纳3个苹果
  BlockingQueue<String> basket = new ArrayBlockingQueue<String>(3);

  // 生产苹果,放入篮子
  public void produce() throws InterruptedException{
   // put方法放入一个苹果,若basket满了,等到basket有位置
   basket.put("An apple");
  }
  // 消费苹果,从篮子中取走
  public String consume() throws InterruptedException{
   // get方法取出一个苹果,若basket为空,等到basket有苹果为止
   String apple = basket.take();
   return apple;
  }

  public int getAppleNumber(){
   return basket.size();
  }

 }
 // 测试方法
 public static void testBasket() {
  // 建立一个装苹果的篮子
  final Basket basket = new Basket();
  // 定义苹果生产者
  class Producer implements Runnable {
   public void run() {
    try {
     while (true) {
      // 生产苹果
      System.out.println("生产者准备生产苹果:"
        + System.currentTimeMillis());
      basket.produce();
      System.out.println("生产者生产苹果完毕:"
        + System.currentTimeMillis());
      System.out.println("生产完后有苹果:"+basket.getAppleNumber()+"个");
      // 休眠300ms
      Thread.sleep(300);
     }
    } catch (InterruptedException ex) {
    }
   }
  }
  // 定义苹果消费者
  class Consumer implements Runnable {
   public void run() {
    try {
     while (true) {
      // 消费苹果
      System.out.println("消费者准备消费苹果:"
        + System.currentTimeMillis());
      basket.consume();
      System.out.println("消费者消费苹果完毕:"
        + System.currentTimeMillis());
      System.out.println("消费完后有苹果:"+basket.getAppleNumber()+"个");
      // 休眠1000ms
      Thread.sleep(1000);
     }
    } catch (InterruptedException ex) {
    }
   }
  }

  ExecutorService service = Executors.newCachedThreadPool();
  Producer producer = new Producer();
  Consumer consumer = new Consumer();
  service.submit(producer);
  service.submit(consumer);
  // 程序运行10s后,所有任务停止
  try {
   Thread.sleep(10000);
  } catch (InterruptedException e) {
  }
  service.shutdownNow();
 }

 public static void main(String[] args) {
  BlockingQueueTest.testBasket();
 }
}

相关文章

  • Springboot集成Jasypt实现配置文件加密的方法

    Springboot集成Jasypt实现配置文件加密的方法

    Jasypt是一个java库,它允许开发员以最少的努力为他/她的项目添加基本的加密功能,并且不需要对加密工作原理有深入的了解,这篇文章主要介绍了Springboot集成Jasypt实现配置文件加密,需要的朋友可以参考下
    2023-04-04
  • 教你怎么用Java获取国家法定节假日

    教你怎么用Java获取国家法定节假日

    这篇文章主要介绍了教你怎么用Java获取国家法定节假日,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-04-04
  • 线程池ThreadPoolExecutor并行处理实现代码

    线程池ThreadPoolExecutor并行处理实现代码

    这篇文章主要介绍了线程池ThreadPoolExecutor并行处理实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • redis redisson 限流器的实例(RRateLimiter)

    redis redisson 限流器的实例(RRateLimiter)

    这篇文章主要介绍了redis redisson 限流器的实例(RRateLimiter),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Netty如何设置为Https访问

    Netty如何设置为Https访问

    这篇文章主要介绍了Netty如何设置为Https访问,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • JDK数组阻塞队列源码深入分析总结

    JDK数组阻塞队列源码深入分析总结

    在这篇文章当中,我们将通过源码仔细为大家介绍一下JDK具体是如何实现数组阻塞队列的,文中的示例代码讲解详细,感兴趣的可以了解一下
    2022-08-08
  • java普通项目读取不到resources目录下资源文件的解决办法

    java普通项目读取不到resources目录下资源文件的解决办法

    这篇文章主要给大家介绍了关于java普通项目读取不到resources目录下资源文件的解决办法,Web项目中应该经常有这样的需求,在maven项目的resources目录下放一些文件,比如一些配置文件,资源文件等,需要的朋友可以参考下
    2023-09-09
  • Java中判断字符串是否相等的实现

    Java中判断字符串是否相等的实现

    这篇文章主要介绍了Java中判断字符串是否相等的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • Java并发编程之详解ConcurrentHashMap类

    Java并发编程之详解ConcurrentHashMap类

    在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口、ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue、BlockingDeque接口,本文为系列文章第八篇.需要的朋友可以参考下
    2021-06-06
  • 解决SpringBoot使用devtools导致的类型转换异常问题

    解决SpringBoot使用devtools导致的类型转换异常问题

    这篇文章主要介绍了解决SpringBoot使用devtools导致的类型转换异常问题,具有很好的参考价值,希望对大家有所帮助。 一起跟随小编过来看看吧
    2020-08-08

最新评论