`
roadrunner
  • 浏览: 17063 次
  • 性别: Icon_minigender_1
  • 来自: 无锡
文章分类
社区版块
存档分类
最新评论

Java Concurrent框架之阻塞队列(Blocking queue)

阅读更多

原文地址:http://www.blogjava.net/fidodido/archive/2005/10/11/15269.html

 

引子:
大家上过操作系统的都知道“生产者-消费者(Producer-Consumer)”模型,主要讨论的是进程(线程)间的互斥和同步问题,关键是对锁(lock)的申请、独占和释放,在这里我就不罗嗦了。原先我写的Java代码如下:

 

public class Producer extends Thread{
  private ProductList products = ProductList.getInstance();
  
  public void run(){
    int i = 0;
    
    while(i <= 20){
      synchronized(products){ // Get lock on product list
    if(products.isFull()){
      System.out.println("List is full");
      products.notify(); // Release the lock
    } else{
      Product product = new Product(i++); // Produce a product
      products.put(product);
      System.out.println("Produced product " + product.getId());
      products.notify(); // Release lock
    }
      } // Release the lock
    }
  }
}

  

public class Consumer extends Thread{
  ProductList products = ProductList.getInstance();
  
  public void run(){
    while(true){
      synchronized(products){
    try {
      products.wait(); // Wait for lock
      Product product = null;
      if(!(products.isEmpty()))
        product = products.take();
      else
        System.out.println("List is empty");
      System.out.println("Consumed product " + product.getId()); // Get the lock
    } catch (InterruptedException ex) {
      ex.printStackTrace();
    }
      } // Release the lock
    }
  }
}

  

import java.util.ArrayList;
import java.util.List;

public class ProductList {
  private static ProductList instance = new ProductList();
  private List<Product> products; // Adapter pattern
  public static final int SIZE = 10;
  
  private ProductList() {
    products = new ArrayList<Product>(SIZE);
  }
  
  public static ProductList getInstance() { // Singleton pattern
    return instance;
  }
  
  public boolean isFull() {
    return products.size() == SIZE;
  }
  
  public void put(Product product) {
    products.add(product);
  }
  
  public Product take() {
    return products.remove(0);
  }
  
  public boolean isEmpty() {
    return products.isEmpty();
  }
}

 

public class Product {
  private int id;
  
  public Product(int id) {
    this.id = id;
  }
  
  public int getId() {
    return id;
  }
}

 

public class Main {
  public static void main(String[] args){
    Producer p = new Producer();
    Consumer c = new Consumer();
    
    p.start();
    c.start();
  }
}

 

虽然Java对信号量及原语做了更高层次的封装(wait()、notify()、notifyAll()、synchronized{}),但看完上述代码还是觉得有点麻烦,于是JDK 5在原先collection框架的基础上增加了java.util.concurrent包,封装了许多用于线程并发操作的数据结构和操作。其中的BlockingQueue接口就是封装了一个阻塞队列的接口,具体地说就是实现了一个用于消费者(多个)和生产者(多个)交换产品的中介,生产者线程在队列满时阻塞,消费者线程在队列空时阻塞,当然在没有得到锁之前两类线程均会阻塞。详细信息可以参考Java Doc。下面用BlockingQueue实现P-C模型:

 

class Producer implements Runnable {
   private final BlockingQueue queue;
   Producer(BlockingQueue q) { queue = q; }
   public void run() {
     try {
       while(true) { queue.put(produce()); }
     } catch (InterruptedException ex) {/* handle */}
   }
   Object produce() {/*...  */}
 }

 class Consumer implements Runnable {
   private final BlockingQueue queue;
   Consumer(BlockingQueue q) { queue = q; }
   public void run() {
     try {
       while(true) { consume(queue.take()); }
     } catch (InterruptedException ex) { /* handle */ }
   }
   void consume(Object x) {/*...*/ }
 }

 class Setup {
   void main() {
     BlockingQueue q = new SomeQueueImplementation();
     Producer p = new Producer(q);
     Consumer c1 = new Consumer(q);
     Consumer c2 = new Consumer(q);
     new Thread(p).start();
     new Thread(c1).start();
     new Thread(c2).start();
   }
 }

 

可以看出代码中没有出现wait()或notify()之类的原语操作,这些操作由concurrent框架负责封装。更全面的讨论可以参考驯服 Tiger: 并发集合(IBM)

分享到:
评论

相关推荐

    阻塞队列(Blocking Queue)是一个支持两个附加操作的队列.txt

    阻塞队列是Java中并发编程的一个重要组件,它属于Java.util.concurrent包中的一部分。阻塞队列的主要特点在于它支持两个额外的条件操作:当队列为空时,尝试从队列中取元素的操作会被阻塞,直到队列中出现新的元素;...

    Blocking Queue Usage

    在Java并发编程中,Blocking Queue(阻塞队列)是一个非常重要的工具类,它结合了线程同步与队列数据结构,有效地实现了生产者消费者模式。 Blocking Queue接口位于java.util.concurrent包下,它提供了一种在多线程...

    java线程聊天室(阻塞队列实现)

    而阻塞队列(Blocking Queue)是Java并发包(java.util.concurrent)中的一种高效数据结构,常用于线程间的协作,它能够简化同步问题并提高系统性能。 阻塞队列是一种特殊的队列,当队列为空时,取出元素的操作将会...

    支持多线程和泛型的阻塞队列

    阻塞队列(Blocking Queue)是线程安全的数据结构,它结合了队列的先进先出(FIFO)原则和等待机制。当队列为空时,尝试获取元素的线程会被阻塞,直到队列中有新的元素;当队列满时,尝试插入元素的线程也会被阻塞,...

    spring MVC 初始启动blocking queue

    在Spring MVC框架中,`BlockingQueue`是一种常用于并发编程的数据结构,它是Java并发包`java.util.concurrent`下的核心组件。`BlockingQueue`是线程安全的队列,它提供了在生产者和消费者之间同步数据的方法,使得一...

    java阻塞队列实现原理及实例解析.docx

    Java 阻塞队列(Blocking Queue)是一种特殊类型的并发数据结构,它在多线程编程中扮演着重要的角色。阻塞队列的核心特性在于其在队列为空或满时能够自动阻塞线程,从而实现线程间的同步和通信。这种机制使得生产者...

    BlockingFQueue:基于磁盘持久存储的阻塞队列(Fast and Persistent Blocking Queue)

    在Java编程中,阻塞队列(Blocking Queue)是一种线程安全的数据结构,它在并发编程中扮演着重要角色,用于实现生产者消费者模型。通常,Java中的阻塞队列如`ArrayBlockingQueue`、`LinkedBlockingQueue`等都是内存...

    BlockingQueue(阻塞队列)详解

    在Java平台中,`java.util.concurrent`包提供了丰富的工具来支持高效的多线程编程,其中`BlockingQueue`接口便是其中之一。它提供了一种线程安全的方式来存储和检索对象,特别适用于生产者-消费者模式等场景。 ####...

    DataStructure-Queue

    - **并发队列(Concurrent Queue)**:在多线程环境中,允许多个线程同时进行入队和出队操作,通常需要复杂的同步机制,如Java的`java.util.concurrent`包中的队列。 通过分析这个项目的代码,我们可以学习到如何在...

    Java_0613_java_源码

    在Java编程语言中,"优先阻塞队列"(Priority Blocking Queue)是一个高效且功能强大的数据结构,它结合了队列的先进先出(FIFO)原则与堆的优先级特性。优先阻塞队列主要用在多线程环境中,为并发处理提供了便利。...

    基于java中BlockingQueue的使用介绍

    Java的并发编程框架提供了多种高级并发工具,其中BlockingQueue是一种非常实用的数据结构,它实现了生产者-消费者模式。在多线程环境下,BlockingQueue可以高效地处理线程间的通信,确保数据的安全共享。本文将深入...

    数据结构 队列存储

    - **阻塞队列(Blocking Queue)**:在多线程环境中,当队列为空时,出队操作会阻塞,直到有新的元素入队;当队列满时,入队操作也会阻塞,直到有元素被出队。这在并发编程中非常有用,如Java的`java.util....

    java线程文档大全

    14. **阻塞队列(Blocking Queue)和阻塞栈(Blocking Stack)**:Java并发包中的LinkedBlockingQueue和ArrayBlockingQueue是典型的阻塞队列实现,它们在插入和移除元素时能自动处理线程阻塞。Deque接口的实现如...

    JavaAPI超全

    - `java.util`包:包含集合框架、日期时间、泛型、队列、栈、排序等工具类,如ArrayList、HashMap、LinkedList等。 2. **Java集合框架**: - 集合接口:如List、Set、Queue,以及它们的实现类如ArrayList、...

    enlfq:Erlang NIF无锁队列

    Enlfq 使用以下库的简单NIF无锁队列: moodycamel :: ConcurrentQueue C ++的工业强度无锁队列。 特点: 击倒你的袜子,快速的表现。 单头实现。 只需将其放入您的项目中即可。 完全线程安全的无锁队列。 从任何数量...

    sheng xiao.rar_生产者消费者

    3. **阻塞队列(Blocking Queue)**:这是一种特殊的队列,当队列满时,添加元素的尝试会阻塞,直到队列有空间;当队列空时,获取元素的尝试会阻塞,直到队列中有元素。Java的`java.util.concurrent`包提供了`...

    线程创建和线程间的通信

    4. 队列:包括阻塞队列(Blocking Queue)和生产者-消费者模型,线程可以在队列中放入或取出元素,达到同步和通信的目的。 5. 管道(Pipe)和通道(Channel):在某些系统中,线程可以通过管道或通道直接传递数据,...

    【每日爬虫】:生产者与消费者模式爬取王者荣耀壁纸

    在多线程编程中,生产者与消费者模式是一种经典的并发设计模式,...在实际编程时,可以根据需求选择合适的阻塞队列实现,如Python的`multiprocessing.Queue`或`concurrent.futures.Queue`等,以适应不同的并发场景。

    producer-consumer-model:生产者-消费者模型

    1. **阻塞队列(Blocking Queue)**:Java中的`BlockingQueue`接口提供了`put()`和`take()`方法。当队列满时,`put()`方法会阻塞生产者线程,直到有空间可用;同样,当队列空时,`take()`方法会阻塞消费者线程,直到...

Global site tag (gtag.js) - Google Analytics