zoukankan      html  css  js  c++  java
  • 阻塞队列BlockingQueue

    BlockingQueue最终会有四种状况,抛出异常、返回特殊值、阻塞、超时,下表总结了这些方法:

    抛出异常

    特殊值

    阻塞

    超时

    插入

    add(e)

    offer(e)

    put(e)

    offer(e, time, unit)

    移除

    remove()

    poll()

    take()

    poll(time, unit)

    检查

    element()

    peek()

    不可用

    不可用

           

     

     

     

     

     

    BlockingQueue是个接口,有如下实现类:

           1. ArrayBlockQueue:一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。创建其对象必须明确大小,像数组一样。

           2. LinkedBlockQueue:一个可改变大小的阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。创建其对象如果没有明确大小,默认值是Integer.MAX_VALUE。链接队列的吞吐量通常要高于基于数组的队列,但是在大多数并发应用程序中,其可预知的性能要低。 

           3. PriorityBlockingQueue:类似于LinkedBlockingQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数所带的Comparator决定的顺序。

           4. SynchronousQueue:同步队列。同步队列没有任何容量,每个插入必须等待另一个线程移除,反之亦然

           下面使用ArrayBlockQueue来实现之前实现过的生产者消/费者模式,代码如下:

    1. /** 定义一个盘子类,可以放鸡蛋和取鸡蛋 */  
    2. public class BigPlate {  
    3. /** 装鸡蛋的盘子,大小为5 */  
    4. private BlockingQueue<Object> eggs = new ArrayBlockingQueue<Object>(5);  
    5. /** 放鸡蛋 */  
    6. public void putEgg(Object egg) {  
    7. try {  
    8. eggs.put(egg);// 向盘子末尾放一个鸡蛋,如果盘子满了,当前线程阻塞  
    9. catch (InterruptedException e) {  
    10. e.printStackTrace();  
    11. }  
    12. // 下面输出有时不准确,因为与put操作不是一个原子操作  
    13. System.out.println("放入鸡蛋");  
    14. }  
    15. /** 取鸡蛋 */  
    16. public Object getEgg() {  
    17. Object egg = null;  
    18. try {  
    19. egg = eggs.take();// 从盘子开始取一个鸡蛋,如果盘子空了,当前线程阻塞  
    20. catch (InterruptedException e) {  
    21. e.printStackTrace();  
    22. }  
    23. // 下面输出有时不准确,因为与take操作不是一个原子操作  
    24. System.out.println("拿到鸡蛋");  
    25. return egg;  
    26. }  
    27. /** 放鸡蛋线程 */  
    28. static class AddThread extends Thread {  
    29. private BigPlate plate;  
    30. private Object egg = new Object();  
    31. public AddThread(BigPlate plate) {  
    32. this.plate = plate;  
    33. }  
    34. public void run() {  
    35. plate.putEgg(egg);  
    36. }  
    37. }  
    38. /** 取鸡蛋线程 */  
    39. static class GetThread extends Thread {  
    40. private BigPlate plate;  
    41. public GetThread(BigPlate plate) {  
    42. this.plate = plate;  
    43. }  
    44. public void run() {  
    45. plate.getEgg();  
    46. }  
    47. }  
    48. public static void main(String[] args) {  
    49. BigPlate plate = new BigPlate();  
    50. // 先启动10个放鸡蛋线程  
    51. for(int i = 0; i < 10; i++) {  
    52. new Thread(new AddThread(plate)).start();  
    53. }  
    54. // 再启动10个取鸡蛋线程  
    55. for(int i = 0; i < 10; i++) {  
    56. new Thread(new GetThread(plate)).start();  
    57. }  
    58. }  
    59. }  
  • 相关阅读:
    session笔记-韩顺平
    带宽
    cookie-韩顺平
    分层模式开发+MVC模式开发--韩顺平雇员数据库管理
    韩顺平-雇员管理系统-学习小结
    常用的PHP数据库操作方法(MYSQL版)
    使用Three.js 基本组件以及流程
    three.js 相机
    多线程的操作与数据绑定
    矩阵-
  • 原文地址:https://www.cnblogs.com/m2492565210/p/7468392.html
Copyright © 2011-2022 走看看