zoukankan      html  css  js  c++  java
  • Java多线程与并发库高级应用之阻塞队列BlockingQueue

    JDK1.5提供了阻塞队列接口BlockingQueue,它是一个有界阻塞队列。BlockingQueue实现是线程安全的,可以安全地与多个生产者和多个使用者一起使用。

    使用时用其实现类 ArrayBlockingQueue,它一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。队列的头部 是在队列中存在时间最长的元素。队列的尾部是在队列中存在时间最短的元素。新元素插入到队列的尾部,队列获取操作则是从队列头部开始获得元素。
    这是一个典型的“有界缓存区”,固定大小的数组在其中保持生产者插入的元素和使用者提取的元素。一旦创建了这样的缓存区,就不能再增加其容量。试图向已满队列中放入元素会导致操作受阻塞;试图从空队列中提取元素将导致类似阻塞。

    使用构造器ArrayBlockingQueue(int capacity)可以创建一个带有给定的(固定)容量和默认访问策略的ArrayBlockingQueue。
     
    其put(E e)方法将指定的元素插入此队列的尾部,如果该队列已满,则等待可用的空间。
    take()方法可以获取并移除此队列的头部,在元素变得可用之前一直等待。

    见下面程序,程序中两条线程向队列中写入数据,一条线程读取数据。当队列已满时,写入线程阻塞;当队列空时,读取线程阻塞。
    1. public class ArrayBlockingQueueDemo {  
    2.   
    3.     public static void main(String[] args) {  
    4.           
    5.         //阻塞队列,队列容量为3  
    6.         final BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(3);  
    7.           
    8.         //两个线程向队列写入数据  
    9.         for(int i = 0; i < 2; i++){  
    10.             new Thread(){  
    11.                 @Override  
    12.                 public void run() {  
    13.                     while(true){  
    14.                         try{  
    15.                             Thread.sleep((long)(Math.random()*1000));  
    16.                             System.out.println(getName() + "-准备向队列写入数据");  
    17.                             queue.put(1);  
    18.                             System.out.println(getName() + "-已经向队列写入数据,队列一共有"  
    19.                                     + queue.size() + "个数据");  
    20.                         }catch(InterruptedException e){  
    21.                             e.printStackTrace();  
    22.                         }  
    23.                     }  
    24.                 }  
    25.             }.start();  
    26.         }  
    27.           
    28.         //一个线程读取数据  
    29.         new Thread(){  
    30.             @Override  
    31.             public void run() {  
    32.                 while(true){  
    33.                     try{  
    34.                         Thread.sleep(1000);  
    35.                         System.out.println(getName() + "-准备从队列读取数据");  
    36.                         queue.take();  
    37.                         System.out.println(getName() + "-已经从队列读取数据,队列一共有"  
    38.                                 + queue.size() + "个数据");  
    39.                     }catch(InterruptedException e){  
    40.                         e.printStackTrace();  
    41.                     }  
    42.                 }  
    43.             }  
    44.         }.start();  
    45.     }  
    46.   
    47. }  

    运行程序


    看到当队列已满时,写入线程阻塞知道有一个数据被取出后才能继续写入。
  • 相关阅读:
    解决SSH窗口关闭,linux上的应用也关闭
    Spring 自定义配置类bean
    java 图片文字识别 ocr
    解决Oracle在Linux下Listener起不来,error 111错误
    java 切图 判断图片是否是纯色/彩色图片
    java 二维码编码解码
    字符串整体大小写转换,首字母大小写
    oracle 解锁表的一个小问题
    mysql-如何完全删除主从同步
    oracle RAC ONLINE INTERMEDIATE shdb1 Stuck Archiver
  • 原文地址:https://www.cnblogs.com/sfce/p/3701827.html
Copyright © 2011-2022 走看看