阻塞与非阻塞:

  阻塞:

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

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

    我们可以通过一定的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. httplib模块:(一个相对底层的http请求模块)

    httplib是一个相对底层的http请求模块,期上有专门的包装模块,如urllib内建模块,goto第三方模块,但是封装的越高就约不灵活,比如urllib模块里的请求错误是就不会返回结果页的内容,只 ...

  2. Vue.js——60分钟快速入门 一

    来源:https://www.cnblogs.com/keepfool/p/5619070.html Vue.js介绍 Vue.js是当下很火的一个JavaScript MVVM库,它是以数据驱动和组 ...

  3. Smarty模板引擎模板文件.tpl和.html的区别

    在WEB开发中,PHP作为业务逻辑,HTML作为表现逻辑.但是在Smarty一些文档中可以看到模板文件的拓展名是.tpl,而不是.html,其实所谓的.tpl就是.html. 模版文件可以用任意的扩展 ...

  4. linux使用v 2ray

    一.安装配置服务端程序 是时候使用 了,因为相对安全,使用方法很简单,使用root权限执行以下命令即可 $ sudo -i 一顿安装后如图 输入 命令可以查看链接,然后在客户端使用这个链接就能配置好了 ...

  5. hdu4348 To the moon (可持久化线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4348 题目大意:给定含有n个数的序列,有以下四种操作 1.C l r d:表示对区间[l,r]中的数加 ...

  6. 【Kickstart】2018 Round (Practice ~ C)

    Practice Round Problem A GBus count (9pt/15pt) (2019年1月14日,kickstart群每日一题) 题意:有一条笔直的大路,上面有城市编号从 1 开始 ...

  7. 原生jdbc操作

    1:加入dbcp连接池依赖 <dependency> <groupId>org.apache.commons</groupId> <artifactId> ...

  8. 程序猿看了要xiao了

    一. 程序猿问科比:“你为什么这么成功? ”科比:“你知道洛杉矶凌晨四点是什么样子吗? ”程序猿:“知道,一般那个时候我还在写代码,怎么了?”科比:“额…….” 二. 女神:你能让这个论坛的人都吵起来 ...

  9. selenium设定请求头

    如果只是需要设定User-Agent可以用如下所示方式 dcap = dict(DesiredCapabilities.PHANTOMJS)dcap["phantomjs.page.sett ...

  10. ACM2014-04训练计划

    这是我写的第一篇博文,先简单说说今天的状态吧,毕竟我的第一篇博文是今天诞生的.这学期开学以来各种乱忙,开学初准备高数竞赛决赛,而后有一段时间疯狂学习英语,一直到前几天国创项目中的任务,准备数模竞赛,上 ...