精华内容
下载资源
问答
  • 自定义线程池---使用有界队列承装任务
    2021-04-17 07:10:43

    任务类:

    说明:

    1.初始化

    2.任务执行体

    package cm.pool;

    public class MyTask implements Runnable {

    private int taskId;

    private String taskName;

    public MyTask(int taskId, String taskName) {

    this.taskId = taskId;

    this.taskName = taskName;

    }

    public int getTaskId() {

    return taskId;

    }

    public void setTaskId(int taskId) {

    this.taskId = taskId;

    }

    public String getTaskName() {

    return taskName;

    }

    public void setTaskName(String taskName) {

    this.taskName = taskName;

    }

    @Override

    public void run() {

    try {

    System.out.println(Thread.currentThread().getName()+"-----------run taskId="+this.taskId);

    Thread.sleep(5*1000);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    }

    自定义线程池,有界队列承载任务体。

    说明:

    1.使用有界队列时,若有新的任务执行,如果线程池实际线程不小于corsize,则优先创建线程。

    2.若大于corsize,则将任务加入到队列中,等待第一个任务执行完成之后在执行队列里的任务。

    3.若队列中的任务已满,则在总线程数不大于maxsize前提下,创建一个新的线程(此时已经创建两个线程先执行了两次任务,然后执行队列里存放了的三个任务)

    4.若线程数大于maxsize,则执行拒绝策略,获取其他自定义方法。

    package cm.pool;

    import java.util.concurrent.ArrayBlockingQueue;

    import java.util.concurrent.ThreadPoolExecutor;

    import java.util.concurrent.TimeUnit;

    public class UseThreadpoolExecutor_1 {

    public static void main(String[] args) {

    ThreadPoolExecutor pool = new ThreadPoolExecutor(1, // corSize

    2, // maxPoolSize

    60, // keepAliveTime

    TimeUnit.SECONDS, // unit,

    new ArrayBlockingQueue(3)// workQueue

    );

    MyTask task1 = new MyTask(1, "任务1");

    MyTask task2 = new MyTask(2, "任务2");

    MyTask task3 = new MyTask(3, "任务3");

    MyTask task4 = new MyTask(4, "任务4");

    MyTask task5 = new MyTask(5, "任务5");

    MyTask task6 = new MyTask(6, "任务6");

    pool.execute(task1);

    //2、3、4会放到队列

    pool.execute(task2);

    pool.execute(task3);

    pool.execute(task4);

    pool.execute(task5);

    pool.execute(task6);

    pool.shutdown();

    }

    }

    当承载元素的ArrayBlockingQueue元素存放已满,并且线程超出maxsize,则执行拒绝策略(详看下文...)

    更多相关内容
  • 主要介绍了Java中有界队列的饱和策略(reject policy)原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 阻塞队列,有界队列,无界队列

    千次阅读 2021-03-12 16:01:58
    如果要实现一个线程安全的队列有两种方式:一种是使用阻塞算法,另一种是使用非阻塞算法。 使用阻塞算法的队列可以用一个锁(入队和出队用同一把锁)或两个锁(入队和出队用不同的锁)等方式来实现。非阻塞的实现...

    在并发编程中,有时候需要使用线程安全的队列。如果要实现一个线程安全的队列有两种方式:一种是使用阻塞算法,另一种是使用非阻塞算法。

    使用阻塞算法的队列可以用一个锁(入队和出队用同一把锁)或两个锁(入队和出队用不同的锁)等方式来实现。非阻塞的实现方式则可以使用自旋+CAS的方式来实现。

    基本概念

    阻塞队列与非阻塞队列

    阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作支持阻塞的插入和移除方法。

    • 支持阻塞的插入方法offer:当队列满时,队列会阻塞插入元素的线程,直到队列不满。

    • 支持阻塞的移除方法take:在队列为空时,获取元素的线程会等待队列变为非空。

    阻塞队列常用于生产者和消费者的场景,生产者是向队列里添加元素的线程,消费者是从队列里取元素的线程。阻塞队列就是生产者用来存放元素、消费者用来获取元素的容器。

    非阻塞队列:若队列为空从中获取元素则会返回空,若队列满了插入元素则会抛出异常。

    有界队列与无界队列

    • 有界队列:就是有固定大小的队列。比如设定了固定大小的ArrayBlockingQueue,又或者大小为0,只是在生产者和消费者中做中转用的SynchronousQueue。

    • 无界队列:指的是没有设置固定大小的队列。这些队列的特点是可以直接入列,直到溢出。当然现实几乎不会有到这么大的容量(超过 Integer.MAX_VALUE),所以从使用者的体验上,就相当于 “无界”。

    Java中的阻塞队列

    在这里插入图片描述

    • ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列。

    • LinkedBlockingQueue:一个由链表结构组成的有界阻塞队列。

    • PriorityBlockingQueue:一个支持优先级排序的无界阻塞队列。

    • DelayQueue:一个使用优先级队列实现的延迟无界阻塞队列。

    • SynchronousQueue:一个不存储元素的阻塞队列。

    • LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。

    • LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。

    另外还有一个DelayedWorkQueue,是ScheduledThreadPoolExecutor的内部类。

    阻塞队列中的方法

    方法类型抛出异常特殊值阻塞超时
    插入时队列满了的表现add(IllegalStateException)offer(false)putoffer
    移除时队列为空的表现remove(NoSuchElementException)poll(null)takepoll
    检查时队列为空的表现element(NoSuchElementException)peek(null)不可用不可用

    ArrayBlockingQueue

    基于数组实现的有界阻塞队列,ArrayBlockingQueue内部维护这一个定长数组,阻塞队列的大小在初始化时就已经确定了,其后无法更改。

    ArrayBlockingQueue支持公平性和非公平性,默认采用非公平模式,可以通过构造函数设置为公平访问策略。

    PriorityBlockingQueue

    PriorityBlockingQueue是支持优先级的无界队列。默认情况下采用自然顺序排序,当然也可以通过自定义Comparator来指定元素的排序顺序,不能保证同优先级元素的顺序。

    PriorityBlockingQueue内部采用二叉堆的实现方式。

    DelayQueue

    DelayQueue是一个支持延时操作的无界阻塞队列。列头的元素是最先“到期”的元素,如果队列里面没有元素到期,是不能从列头获取元素的,哪怕有元素也不行。也就是说只有在延迟期满时才能够从队列中去元素。

    它主要运用于如下场景:

    • 缓存系统的设计:缓存是有一定的时效性的,可以用DelayQueue保存缓存的有效期,然后利用一个线程查询DelayQueue,如果取到元素就证明该缓存已经失效了。

    • 定时任务的调度:DelayQueue保存当天将要执行的任务和执行时间,一旦取到元素(任务),就执行该任务。

    DelayQueue采用支持优先级的PriorityQueue来实现,但是队列中的元素必须要实现Delayed接口,Delayed接口用来标记那些应该在给定延迟时间之后执行的对象,该接口提供了getDelay()方法返回元素节点的剩余时间。同时,元素也必须要实现compareTo()方法,compareTo()方法需要提供与getDelay()方法一致的排序。

    SynchronousQueue

    SynchronousQueue是一个神奇的队列,他是一个不存储元素的阻塞队列,也就是说他的每一个put操作都需要等待一个take操作,否则就不能继续添加元素了,有点儿像Exchanger,类似于生产者和消费者进行交换。

    队列本身不存储任何元素,所以非常适用于传递性场景,两者直接进行对接。其吞吐量会高于ArrayBlockingQueue和LinkedBlockingQueue。

    SynchronousQueue支持公平和非公平的访问策略,在默认情况下采用非公平性,也可以通过构造函数来设置为公平性。

    SynchronousQueue的实现核心为Transferer接口,该接口有TransferQueue和TransferStack两个实现类,分别对应着公平策略和非公平策略。接口Transferer有一个tranfer()方法,该方法定义了转移数据,如果e != null,相当于将一个数据交给消费者,如果e == null,则相当于从一个生产者接收一个消费者交出的数据。

    LinkedTransferQueue

    LinkedTransferQueue与其他BlockingQueue相比,他多实现了一个接口TransferQueue,该接口是对BlockingQueue的一种补充,多了tryTranfer()和transfer()两类方法:

    • tranfer():若当前存在一个正在等待获取的消费者线程,即立刻移交之。 否则,会插入当前元素e到队列尾部,并且等待进入阻塞状态,到有消费者线程取走该元素。

    • tryTranfer(): 若当前存在一个正在等待获取的消费者线程(使用take()或者poll()函数),使用该方法会即刻转移/传输对象元素e;若不存在,则返回false,并且不进入队列。这是一个不阻塞的操作。

    LinkedBlockingDeque

    LinkedBlockingDeque是一个有链表组成的双向阻塞队列,与前面的阻塞队列相比它支持从两端插入和移出元素。以first结尾的表示从对头操作,以last结尾的表示从对尾操作。

    在初始化LinkedBlockingDeque时可以初始化队列的容量,用来防止其再扩容时过渡膨胀。另外双向阻塞队列可以运用在“工作窃取”模式中。

    ArrayBlockingQueue的源码分析

    ArrayBlockingQueue,一个由数组实现的有界阻塞队列。该队列采用FIFO的原则对元素进行排序添加的。

    数据结构

    public class ArrayBlockingQueue<E> extends AbstractQueue<E>
            implements BlockingQueue<E>, java.io.Serializable {
    
        final Object[] items; // 存储元素的数组
    
        int takeIndex; // 队首位置
    
        int putIndex; // 队尾位置
    
        int count; // 元素的个数
    
        final ReentrantLock lock; // 锁,出列入列都必须获取该锁,两个步骤共用一个锁
    
        private final Condition notEmpty; // 出队条件
    
        private final Condition notFull; // 入队条件
    

    ArrayBlockingQueue内部使用可重入锁ReentrantLock + Condition来完成多线程环境的并发操作。

    构造方法

    // 指定初始化时元素个数,可见是个有界队列
    public ArrayBlockingQueue(int capacity) {
        this(capacity, false);
    }
    
    // 指定初始化时元素个数和公平策略
    public ArrayBlockingQueue(int capacity, boolean fair) {
        if (capacity <= 0)
            throw new IllegalArgumentException();
        this.items = new Object[capacity];
        lock = new ReentrantLock(fair);
        notEmpty = lock.newCondition();
        notFull =  lock.newCondition();
    }
    
    // 指定初始化时元素个数和公平策略,指定初始化集合中的元素
    public ArrayBlockingQueue(int capacity, boolean fair,
                              Collection<? extends E> c) {
        this(capacity, fair);
    
        final ReentrantLock lock = this.lock;
        lock.lock(); // Lock only for visibility, not mutual exclusion
        try {
            int i = 0;
            try {
                for (E e : c) {
                    checkNotNull(e);
                    items[i++] = e;
                }
            } catch (ArrayIndexOutOfBoundsException ex) {
                throw new IllegalArgumentException();
            }
            count = i;
            putIndex = (i == capacity) ? 0 : i;
        } finally {
            lock.unlock();
        }
    }
    

    offer()

    public boolean offer(E e) {
        checkNotNull(e);
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            if (count == items.length)
                // 队满了
                return false;
            else {
                enqueue(e);
                return true;
            }
        } finally {
            lock.unlock();
        }
    }
    
    // 插入队尾
    private void enqueue(E x) {
        final Object[] items = this.items;
        items[putIndex] = x;
        if (++putIndex == items.length)
            putIndex = 0;
        count++;
        notEmpty.signal();
    }
    

    put()

    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();
        }
    }
    
    private E dequeue() {
        final Object[] items = this.items;
        @SuppressWarnings("unchecked")
        E x = (E) items[takeIndex];
        items[takeIndex] = null;
        if (++takeIndex == items.length)
            takeIndex = 0;
        count--;
        if (itrs != null)
            itrs.elementDequeued();
        notFull.signal();
        return x;
    }
    

    poll()

    public E poll() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            // 队空返回null,不等待
            return (count == 0) ? null : dequeue();
        } finally {
            lock.unlock();
        }
    }
    

    手写阻塞队列

    package com.morris.concurrent.pattern.guardedsuspension;
    
    import java.util.ArrayList;
    
    public class ArrayListBlockingQueue<T> {
    
        private ArrayList<T> taskList;
    
        private int queueSize;
    
        public ArrayListBlockingQueue(int queueSize) {
            this.queueSize = queueSize;
            this.taskList = new ArrayList<>(queueSize);
        }
    
        public void offer(T t) throws InterruptedException {
            synchronized (this.taskList) {
                while(this.taskList.size() == queueSize) {
                    this.taskList.wait();
                }
                this.taskList.add(t);
                this.taskList.notifyAll();
            }
        }
    
        public T take() throws InterruptedException {
            synchronized (this.taskList) {
                while (this.taskList.isEmpty()) {
                    this.taskList.wait();
                }
                this.taskList.notifyAll();
                return this.taskList.remove(0);
            }
        }
    }
    
    展开全文
  • 队列也是一种特殊的线性表,它只允许在两端进行操作,插入或者取出,不允许操作中间的数据。比如只允许在对头出队,队尾入队。这样就具有先进先出的特性(first in first out-FIFO)。就像排队买东西一样,不允许插队...

    队列也是一种特殊的线性表,它只允许在两端进行操作,插入或者取出,不允许操作中间的数据。比如只允许在对头出队,队尾入队。这样就具有先进先出的特性(first in first out-FIFO)。就像排队买东西一样,不允许插队,先排先买。

    队列分为单向队列(有序队列),就是上面所说的排队模型,先进先出的操作,只允许一边进,另一边出,比如Java中的Queue。另外一种就是双端队列,两端都可以进行进出操作。比如java中的Deque。

    既然队列也是线性表的一种,那么实现队列,就可以用数组或者链表来实现。

    如果再细分一点的话,可以看着这俩接口的实现,简单列举几个:

    PriorityQueue:数组实现的有序队列,可以传入一个比较器Comparator,实现队列中元素的顺序。。

    ArrayDeque:数组实现的双端队列

    LinkedList:用链表实现的双端队列

    Juc并发包下面:

    ArrayBlockingQueue:数组实现的阻塞队列

    PriorityBlockingQueue:带优先级的阻塞队列

    LinkedBlockingQueue:链表实现的阻塞队列

    可以看出大佬们的命名是很规范的,从类名直接可以看出来这队列的特性以及用什么数据结构实现的。

    简单用数组实现一个有界队列

    1.初始化一个数组,这个是头尾都是指向的0

    1bb7ab748497aeaa4cfae3f8a489e2bf.png

    2.插入三个元素,尾移动三位,指向了3

    64c7cd79c7f668eb5f62fa9bf503f09b.png

    3.取出一个元素,头移动一位指向了1

    1878b44474d6ed04bbee540aa55333c4.png

    我们会发现头指针走过的数组元素其实是空出来了的(index = 0)。假设尾指针走到最后了,但是因为我们有取出元素,前面有空位,所以按理来说,我们还可以继续加入元素进去,但是这个时候怎么指针怎么回去呢?可以重新创建一个数组继续开始,这样的话会重新开辟内存空间,而且还需要将现有的数据复制到新的数组中去。如果我们只想让这个队列保持初始化大小,没有扩容操作,创建一个新的数组去继续放,从空间和时间复杂度来说都不合适了。这个时候我们可以通过取模操作,让指针回去,从头开始,既不用开辟新空间,也不用移动数据。这样的话就需要考虑空队列和满队这两个状态的判断。如果满了就无法插入,新数据直接丢弃,按如上逻辑实现一个简单队列。

    packagecom.nijunyang.algorithm.queue;/*** Description:

    * Created by nijunyang on 2020/4/4 21:44*/

    public class MyQueue{private static final int DEFAULT_SIZE = 10;privateObject[] elements;private intheadIndex;private inttailIndex;private int capacity; //从容量

    private int size; //已放元素个数

    publicMyQueue() {this(DEFAULT_SIZE);

    }public MyQueue(intcapacity) {this.elements = newObject[capacity];this.capacity =capacity;

    }public voidpush(E e){if (isFull()) { //插入先判断是否满

    return;

    }

    elements[tailIndex]=e;

    size++;

    tailIndex= (tailIndex + 1) % capacity; //取模实现循环的操作

    }publicE pop(){if(isEmpty()) { //取元素先判空

    return null;

    }

    E e=(E) elements[headIndex];

    headIndex= (headIndex + 1) % capacity; //取模实现循环的操作

    size--;returne;

    }public booleanisEmpty(){return this.size == 0;

    }public intsize(){return this.size;

    }public intgetCapacity(){return this.capacity;

    }public booleanisFull(){return this.size == this.capacity;

    }public static voidmain(String[] args) {

    MyQueue myQueue = new MyQueue(3);

    myQueue.push(1);

    System.out.println(myQueue.size());

    myQueue.push(2);

    myQueue.push(3);

    System.out.println(myQueue.pop());

    System.out.println(myQueue.size());

    myQueue.push(4);

    myQueue.push(5);

    System.out.println(myQueue.size());

    }

    }

    展开全文
  • 聊聊Java中的并发队列中 有界队列和无界队列的区别

    本文主要总体的说一说各种并发队列 
    首先来一张全体照 
    这里写图片描述

    从有界无界上分 
    常见的有界队列为

    • ArrayBlockingQueue 基于数组实现的阻塞队列
    • LinkedBlockingQueue 其实也是有界队列,但是不设置大小时就时Integer.MAX_VALUE,内部是基于链表实现的
    • ArrayBlockingQueue 与 LinkedBlockingQueue 对比一哈 
      • ArrayBlockingQueue 实现简单,表现稳定,添加和删除使用同一个锁,通常性能不如后者
      • LinkedBlockingQueue 添加和删除两把锁是分开的,所以竞争会小一些
    • SynchronousQueue 比较奇葩,内部容量为零,适用于元素数量少的场景,尤其特别适合做交换数据用,内部使用 队列来实现公平性的调度,使用栈来实现非公平的调度,在Java6时替换了原来的锁逻辑,使用CAS代替了
    • 上面三个队列他们也是存在共性的 
      • put take 操作都是阻塞的
      • offer poll 操作不是阻塞的,offer 队列满了会返回false不会阻塞,poll 队列为空时会返回null不会阻塞
      • 补充一点,并不是在所有场景下,非阻塞都是好的,阻塞代表着不占用CPU,在有些场景也是需要阻塞的,put take 存在必有其存在的必然性

    常见的无界队列

    • ConcurrentLinkedQueue 无锁队列,底层使用CAS操作,通常具有较高吞吐量,但是具有读性能的不确定性,弱一致性——不存在如ArrayList等集合类的并发修改异常,通俗的说就是遍历时修改不会抛异常
    • PriorityBlockingQueue 具有优先级的阻塞队列
    • DelayedQueue 延时队列,使用场景 
      • 缓存:清掉缓存中超时的缓存数据
      • 任务超时处理
      • 补充:内部实现其实是采用带时间的优先队列,可重入锁,优化阻塞通知的线程元素leader
    • LinkedTransferQueue 简单的说也是进行线程间数据交换的利器,在SynchronousQueue 中就有所体现,并且并发大神 Doug Lea 对其进行了极致的优化,使用15个对象填充,加上本身4字节,总共64字节就可以避免缓存行中的伪共享问题,其实现细节较为复杂,可以说一下大致过程: 
      • 比如消费者线程从一个队列中取元素,发现队列为空,他就生成一个空元素放入队列 , 所谓空元素就是数据项字段为空。然后消费者线程在这个字段上旅转等待。这叫保留。直到一个生产者线程意欲向队例中放入一个元素,这里他发现最前面的元素的数据项字段为 NULL,他就直接把自已数据填充到这个元素中,即完成了元素的传送。大体是这个意思,这种方式优美了完成了线程之间的高效协作。参考自 
        LinkedTransferQueue_浩子的博客-CSDN博客_linkedtransferqueue
    • 现在也来说一说无界队列的共同点 
      • put 操作永远都不会阻塞,空间限制来源于系统资源的限制
      • 底层都使用CAS无锁编程

       转载自 聊聊Java中的并发队列中 有界队列和无界队列的区别_dayformyjob-CSDN博客_有界队列和无界队列

    展开全文
  • 怎么理解无界队列和有界队列

    万次阅读 2018-11-01 14:53:11
    有界队列:就是固定大小的队列。比如设定了固定大小的 LinkedBlockingQueue,又或者大小为 0,只是在生产者和消费者中做中转用的 SynchronousQueue。 无界队列:指的是没有设置固定大小的队列。这些队列的特点是...
  • 严格的lru算法 1.基于读 更新时间, 2.并且要消除偶尔读对整体数据的影响. 也就是说要考虑 最近x小时内读的次数. 和 最近读的次数. 实现上, 需要个队列... 有界队列实现 需要个淘汰机制. 利用linkedHashMap可以实现
  • 1.2 LinkedBlockingQueue 基于链表实现的阻塞队列,该有界队列不设置大小时就是Integer.MAX_VALUE 其实也是有界队列,但是不设置大小时就时Integer.MAX_VALUE,内部是基于链表实现的 ArrayBlockingQueue 与 ...
  • java线程池的应用-有界队列线程池

    千次阅读 2018-10-17 17:12:53
    我用到是有界队列的线程池。 如果需要返回值,则需要实现Callable接口,并用Future对象去接收,用.get()方法即可得到返回值 线程池大小maximumPoolSize我设置为8,一般情况下设置为内核数的两倍(个人经验) ...
  • 本文主要总体的说一说各种并发队列 ...LinkedBlockingQueue 其实也是有界队列,但是不设置大小时就时Integer.MAX_VALUE,内部是基于链表实现的 ArrayBlockingQueue 与 LinkedBlockingQueue 对比一哈 ArrayBloc...
  • package test.liuwei; import lombok.extern.slf4j.Slf4j; import java.util.concurrent.*;... * @desc 使用界线程池和有界队列的任务调度器 * 一个任务调度器关联一个线程池和一个任务等候队列 * 界的线...
  • 学到更多。 开发更多。 连接更多。 新的developerWorks Premium会员计划可通过Safari图书在线获得对强大的开发工具和资源的无障碍访问权,其中包括500个顶级技术标题(数十个专门针对Java开发人员),主要开发人员...
  • 有界队列和无界队列的区别

    千次阅读 2019-07-19 11:28:00
    参考:https://blog.csdn.net/u012240455/article/details/81844007 转载于:https://my.oschina.net/u/41...
  • 文章目录1、队列和栈2、有限队列2.1、SynchronousQueue:2.2、 ArrayBlockingQueue:3、 无限队列3.1、 LinkedBlockingQueue:3.2、 LinkedBlockingDeque3.3、PriorityBlockingQueue3.4、LinkedTransferQueue ...
  •  ArrayBlockingQueue : 有界队列助于防止资源耗尽,一旦达到上限,可能会造成新任务丢失  newSingleThreadExecutor、newFixedThreadPool使用的是LinkedBlockingQueue  newCachedThreadPool 使用的是 ...
  • 在使用有界队列时,若新的任务需要执行,如果线程池实际线程数小于corePoolSize,则优先创建线程,  若大于corePoolSize,则会将任务加入队列,  若队列已满,则在总线程数不大于maximumPoolSize的前提下,...
  • java实现有界队列

    千次阅读 2017-09-28 17:21:53
    import java.util.LinkedList; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger;... * 有界队列的基本实现 */ public class MyQueue { private LinkedList<Obj
  • 有界队列和无界队列

    千次阅读 2017-05-19 11:14:42
    1、无界队列 2、有界队列
  • java中有界队列的饱和策略(reject policy) 我们在使用ExecutorService的时候知道,在ExecutorService中个一个Queue来保存提交的任务,通过不同的构造函数,我们可以创建无界的队列(ExecutorServ...
  • 有界队列

    2018-09-09 15:30:45
    有界队列 一种特殊的队列,当队列为空时,队列的获取将会阻塞获取线程,直到队列中新增元素,当队列已满时,队列的插入操作将会阻塞插入线程,直到队列出现“空位”。 package com.mutithread.chapter5; ...
  • import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class UseExecutors { public static void main(String[] arg...
  • 有界队列可以避免内存溢出: 1、当等待任务队列满了,线程池中的线程也在执行任务时,则会创建额外的最多maximumPoolSize的线程去处理新提交的任务; 2、当可以无限制地创造额外的新线程出来,则可能导致机器上几...
  • 自定义线程池-有界队列

    千次阅读 2017-05-19 14:00:22
     * 有界队列 corePoolSize ,如果线程数小于 corePoolSize 则会创建线程,  * 到达 corePoolSize 后不会在继续创建线程,任务就扔到队列里  * 如果任务创建和处理的速度差异很大,无界队列会保持快速增长...
  •  * 使用有界队列时,如果新任务  */ ThreadPoolExecutor pool = new  ThreadPoolExecutor(1,  2,  60,  TimeUnit. SECONDS ,   new  ArrayBlockingQueue(3) //指定有界队列   //...
  • 线程- Condition实现 有界队列设计思路测试 设计思路 BoundedQueue boundedQueue = new BoundedQueue(2); BoundedQueue 初始化,并设置队列的大小 count 为 2 add(T t),往队列中添加元素,如果队列中的长度不大于 ...
  • 实现一个自定义的有界阻塞队列. 当队列为空时,阻塞直到可取的元素被唤醒;当队列满时,阻塞直到空间存放元素被唤醒.分析:1)为实现有界: 采用数组进行存储元素模拟队列,为了提高空间的利用率,使用循环队列2)为实现...
  • 队列的本质是内存,线程的本质是cpu 线程池的两个方法:submit方法中调用的execute方法,但是submit方法返回值; Java提供了4钟线程池: newCachedThreadPool newFixedThreadPool newSingleThreadExecutor ...
  • 今天在公司因为业务需求用到java....支持多线程安全的有界队列。涉及volatile,AtmicInteger等应用。定义队列满时候的丢弃策略。 import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.at

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 50,699
精华内容 20,279
关键字:

有界队列