似懂非懂的SynchronousQueue和长度为1的BlockingQueue

阅读ArrayBlockingQueue源码,很容易知道有界阻塞队列的长度至少为1,也就是至少能缓存下一个数据。SynchronousQueue的javadoc文档提到A synchronous queue does not have any internal capacity, not even a capacity of one.也就说同步队列的容量是0,不会缓存数据。

长度为1的阻塞队列和SynchronousQueue都能够实现以下效果:插入数据的线程和获取数据的线程,交替执行。

public class TestSynchronousQueue
{
    private static SynchronousQueue<String> queue = new SynchronousQueue<String>();

    public static void main(String[] args) throws Exception
    {
        new Productor().start();
        new Productor().start();
        System.out.println("Productors are blocked.");
        // new Consumer().start();
    }

    static class Productor extends Thread
    {
        @Override
        public void run()
        {
            try
            {
                queue.put("11");
                System.out.println("put success.");
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }

    static class Consumer extends Thread
    {
        @Override
        public void run()
        {
            try
            {
                String v = queue.take();
                System.out.println("take success." + v);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }
}

如果使用同步队列,2个生产者都会被阻塞;如果使用长度为1的有界队列,只有1个生产者会被阻塞。不知道这些差别背后隐藏着什么,不太明白同步队列的使用场景,有知道的兄弟,欢迎回帖。

Executors.newCachedThreadPool()中使用到了同步队列,目的就是保证“对于提交的任务,如果有空闲线程,则使用空闲线程来处理;否则新建一个线程来处理任务”。如果使用长度为1的阻塞队列,则不能达到此效果。

似懂非懂的SynchronousQueue和长度为1的BlockingQueue,布布扣,bubuko.com

时间: 2024-10-16 05:19:55

似懂非懂的SynchronousQueue和长度为1的BlockingQueue的相关文章

【JUC】JDK1.8源码分析之SynchronousQueue(九)

一.前言 本篇是在分析Executors源码时,发现JUC集合框架中的一个重要类没有分析,SynchronousQueue,该类在线程池中的作用是非常明显的,所以很有必要单独拿出来分析一番,这对于之后理解线程池有很有好处,SynchronousQueue是一种阻塞队列,其中每个插入操作必须等待另一个线程的对应移除操作 ,反之亦然.同步队列没有任何内部容量,甚至连一个队列的容量都没有. 二.SynchronousQueue数据结构 由于SynchronousQueue的支持公平策略和非公平策略,所

集合类源码(五)Collection之BlockingQueue(LinkedTransferQueue, PriorityBlockingQueue, SynchronousQueue)

LinkedTransferQueue 功能 全名 public class LinkedTransferQueue<E> extends AbstractQueue<E> implements TransferQueue<E>, Serializable 简述 基于链表的的无界队列.队列的头是某个生产者在队列中停留时间最长的元素.队列的尾部是某个生产者在队列中时间最短的元素. 注意,与大多数集合不同,size方法不是一个常量时间操作.由于这些队列的异步性,确定当前元素

【死磕Java并发】-----J.U.C之阻塞队列:SynchronousQueue

[注]:SynchronousQueue实现算法看的晕乎乎的,写了好久才写完,如果当中有什么错误之处,忘各位指正 作为BlockingQueue中的一员,SynchronousQueue与其他BlockingQueue有着不同特性: 没有容量.与其他BlockingQueue不同,是一个不存储元素的BlockingQueue.每一个put操作必须要等待一个take操作,否则不能继续添加元素,反之亦然. 因为没有容量,所以对应 peek, contains, clear, isEmpty - 等方

SynchronousQueue 的简单应用

SynchronousQueue是这样一种阻塞队列,其中每个 put 必须等待一个 take,反之亦然.同步队列没有任何内部容量,甚至连一个队列的容量都没有.      不能在同步队列上进行 peek,因为仅在试图要取得元素时,该元素才存在:      除非另一个线程试图移除某个元素,否则也不能(使用任何方法)添加元素;也不能迭代队列,因为其中没有元素可用于迭代.队列的头是尝试添加到队列中的首个已排队线程元素: 如果没有已排队线程,则不添加元素并且头为 null.      对于其他 Colle

从一个故障说说Java的三个BlockingQueue

原文地址:http://hellojava.info/?p=464 最近出了个故障,排查的时候耗费了很长的时间,回顾整个排查过程,经验主义在这里起了不好的作用,直接导致了整个故障排查的时间非常长,这个故障的根本原因在于BlockingQueue用的有问题,顺带展开说说Java中常用的几个BlockingQueue:ArrayBlockingQueue.LinkedBlockingQueue和SynchronousQueue. 当时故障的现象是应用处理请求的线程池满了,导致请求处理不了,于是dum

Java线程池与java.util.concurrent

Java(Android)线程池 介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub } }).start(); 那你就out太多了,new Thre

Android Java 线程池 ThreadPoolExecutor源代码篇

线程池简单点就是任务队列+线程组成的. 接下来我们来简单的了解下ThreadPoolExecutor的源代码. 先看ThreadPoolExecutor的简单类图,对ThreadPoolExecutor总体来个简单的认识. 为了分析ThreadPoolExecutor我们得下扯点队列和队列里面的任务这东西. 常见三种BlockingQueue堵塞队列SynchronousQueue,LinkedBlockingQueue,ArrayBlockingQueue当然还有其它的,简单类图(仅仅画了Sy

ExecutorService的十个使用技巧

ExecutorService] (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent /ExecutorService.html)这个接口从Java 5开始就已经存在了.这得追溯到2004年了.这里小小地提醒一下,官方已经不再支持Java 5, Java 6了,Java 7[在半年后也将停止支持 .我之所以会提起ExecutorService这么旧的一个接口是因为,大多数Java程序员并没有搞清楚它的工作原理.关于它可以

Java-SynchronousQueue 阻塞队列小记

在BlockingQueue的子类中有一个SynchronousQueue(同步队列)比较少见,现在做一个简单的介绍,并附加一个简单的例子. SynchronousQueue --JDK1.6介绍: public class SynchronousQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, Serializable 一种阻塞队列,其中每个插入操作必须等待另一个线程的对应移除操作 ,反之亦然