阻塞与非阻塞:

  阻塞:

    阻塞调用是没有获得资源则挂起进程,被挂起的进程进入休眠状态,调用的函数只有在得到结果之后才返回,进程继续。

    对象是否处于阻塞模式和函数是不是阻塞调用有很强的相关性,但并不是一一对应的;阻塞对象上可以有非阻塞的调用方式。

    我们可以通过一定的API去轮询状态,在适当的时候调用阻塞函数,就可以避免阻塞。

  非阻塞:

    非阻塞是不能进行设备操作时不挂起,或返回,或反复查询,直到可以进行操作为止,被调用的函数不会阻塞当前进程,而会立刻返回。

    对于非阻塞对象,调用的函数也可以锁机制进入阻塞调用

  注意:

    阻塞不是低效率,如果设备驱动不阻塞,用户想获取资源只能不断查询,小号CPU阻塞访问时,不能获取资源的进程将进入休眠,将CPU资源让给其他资源。

    阻塞的进程会进入休眠状态,因此,必须确保有一个地方能唤醒休眠的进程。唤醒进程的地方最大可能发生在终端里面,因为硬件资源的获得往往伴随着一个终端。

  

案例代码:主线程生产日志数据,由多线程去消费

public class ArrayBlockingQueueTest {

    public static void main(String[] args) throws Exception {
        //创建一个固定大小的队列
        final BlockingQueue<String> queue = new ArrayBlockingQueue<String>(1);
        //生产数据
        for(int i=0;i<100000;i++){
            queue.put(i+1+"");
        }
        //创建10个消费者
        for(int i=0;i<10;i++){
            new Thread(new Runnable(){
                @Override
                public void run() {
                    while(true){
                        try {
                            String log = queue.take();
                            System.out.println(Thread.currentThread().getName()+"=>"+log);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        }
    }

}

结果输出:

  Thread-0=>1
  Thread-3=>3
  Thread-2=>4
  Thread-1=>2
  Thread-3=>6
  Thread-1=>7
  Thread-0=>5
  Thread-1=>8
  Thread-2=>9
  Thread-2=>10
  Thread-3=>11
  Thread-3=>12
  Thread-1=>13
  Thread-2=>14

 

put原理:

    /**
     * Inserts the specified element at the tail of this queue, waiting
     * for space to become available if the queue is full.
     *
     * @throws InterruptedException {@inheritDoc}
     * @throws NullPointerException {@inheritDoc}
     */
    public void put(E e) throws InterruptedException {
        checkNotNull(e);
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (count == items.length)
                notFull.await();
            enqueue(e);
        } finally {
            lock.unlock();
        }
    }

take原理:

    public E take() throws InterruptedException {
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (count == 0)
                notEmpty.await();
            return dequeue();
        } finally {
            lock.unlock();
        }
    }

ArrayBlockingQueue使用的更多相关文章

  1. 【JUC】JDK1.8源码分析之ArrayBlockingQueue(三)

    一.前言 在完成Map下的并发集合后,现在来分析ArrayBlockingQueue,ArrayBlockingQueue可以用作一个阻塞型队列,支持多任务并发操作,有了之前看源码的积累,再看Arra ...

  2. 阅读ArrayBlockingQueue源码了解如何利用锁实现BlockingQueue

    BlockingQueue是多线程里面一个非常重要的数据结构.在面试的时候,也常会被问到怎么实现BlockingQueue.本篇根据Java7里ArrayBlockingQueue的源码,简单介绍一下 ...

  3. JAVA可阻塞队列-ArrayBlockingQueue子类BlockingQueue的应用,使用它来实现子线程打印10次,主线程打印100次,如此反复

    /** * 使用BlockingQueue实现主子线程互相打印 * @author duwenlei * */ public class BlockingQueueTest { public stat ...

  4. JAVA可阻塞队列-ArrayBlockingQueue

    在前面的的文章,写了一个带有缓冲区的队列,是用JAVA的Lock下的Condition实现的,但是JAVA类中提供了这项功能,就是ArrayBlockingQueue, ArrayBlockingQu ...

  5. Java多线程系列--“JUC集合”07之 ArrayBlockingQueue

    概要 本章对Java.util.concurrent包中的ArrayBlockingQueue类进行详细的介绍.内容包括:ArrayBlockingQueue介绍ArrayBlockingQueue原 ...

  6. Java并发之BlockingQueue 阻塞队列(ArrayBlockingQueue、LinkedBlockingQueue、DelayQueue、PriorityBlockingQueue、SynchronousQueue)

    package com.thread.test.thread; import java.util.Random; import java.util.concurrent.*; /** * Create ...

  7. ArrayBlockingQueue跟LinkedBlockingQueue的区别

    .队列中的锁的实现不同 ArrayBlockingQueue中的锁是没有分离的,即生产和消费用的是同一个锁: LinkedBlockingQueue中的锁是分离的,即生产用的是putLock,消费是t ...

  8. ArrayBlockingQueue,BlockingQueue分析

    BlockingQueue接口定义了一种阻塞的FIFO queue,每一个BlockingQueue都有一个容量,让容量满时往BlockingQueue中添加数据时会造成阻塞,当容量为空时取元素操作会 ...

  9. ArrayBlockingQueue

    ArrayBlockingQueue是阻塞队列的一种,基于数组实现,长度固定,队尾添加,队首获取, 构造函数: p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font ...

  10. ArrayBlockingQueue-我们到底能走多远系列(42)

    我们到底能走多远系列(42) 扯淡: 乘着有空,读些juc的源码学习下.后续把juc大致走一边,反正以后肯定要再来. 主题: BlockingQueue 是什么 A java.util.Queue t ...

随机推荐

  1. 08-js流程控制、循环、元素操作

    # js流程控制 > 流程控制用于基于不同的条件来执行不同的动作. ### if语句 >if... else ... >if ... else if ... else... > ...

  2. Array数组的使用

    public class ArrayDemo { public static void main(String[] args) { int[] arr = {13,44,55,667,67,78}; ...

  3. c#中decimal的去0显示

    在近来的开发中,遇到到了decimal中显示0的问题,搞了很久才搞好了,现在就简单介绍一下其中一小部分,其他的网上很上很多 public static string DecimalToString(d ...

  4. JSP2的自定义标签和方法

    Jsp2的自定义标签 Jsp2 开发标签库的几个步骤: 开发自定义标签处理类. 建立一个*.tld文件,每个tld文件对应一个标签库,每个标签库可对应多个标签. 在jsp文件中使用自定义标签 空标签 ...

  5. 关于使用itext转Html为pdf添加css样式的问题

    使用的jar文件 xmlworker-5.5.11.jar itextpdf-5.5.11.jar 下载地址:https://pan.baidu.com/s/1i5AIBvZ 以下为测试代码 pack ...

  6. CentOS下性能监测工具 dstat

    原文链接:http://www.bkjia.com/Linuxjc/935113.html 参考链接:https://linux.cn/article-3215-1.html,http://lhfli ...

  7. C# 实现实体类和Xml转换

    一.实体类转换成XML 将实体类转换成XML需要使用XmlSerializer类的Serialize方法,将实体类序列化 public static string XmlSerialize<T& ...

  8. 1N4148

    摘自http://baike.baidu.com/link?url=0iTO7zZvHpCeJiZurTPpjDT95YdJu7cKdTeCWfol36b4JG5ii15leQ7K4wJWAZIBNb ...

  9. python 日期封装

    import time import datetime import locale class TimeUtil: def __init__(self, curtime=None): self.cur ...

  10. JavaWeb(四):JDBC

    数据持久化(persistence) 把数据保存到可掉电式存储设备中以供之后使用. 大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存到硬盘上加以”固化”,而持久化的实现过程大多通过各 ...