java多线程:线程池常用的三种队列详解!

开篇:我们在初始化线程池的时候常常会使用到如下三种队列,他们分别是:

LinkedBlockingDeque(链表同步阻塞队列)、ArrayBlockingQueue(数组同步阻塞队列)、SynchronousQueue(同步阻塞队列)

他们与线程池的的maximumPoolSize参数结合使用时会有不同的效果。

通过实验来说明:

1.使用ArrayBlockingQueue

(1).源码

 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();
    }

(2).代码实例

        a.当Runnable的数量小于等于maximumPoolSize与阻塞队列的和

package com.springboot.thread;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadQueueTest {
    public static void main(String[] args) {
        ArrayBlockingQueue linked = new ArrayBlockingQueue(2);
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,3,1L, TimeUnit.SECONDS,linked);
        ThreadQueueRunnable runnable  = new ThreadQueueRunnable();
        System.out.println("before thread pool execute linked size is :"+linked.size());
        threadPoolExecutor.execute(runnable);
        threadPoolExecutor.execute(runnable);
        threadPoolExecutor.execute(runnable);
        threadPoolExecutor.execute(runnable);
        threadPoolExecutor.execute(runnable);
        System.out.println("after thread pool execute linked size is :"+linked.size());
        System.out.println("thread pool size is:" + threadPoolExecutor.getPoolSize());
    }
}


class ThreadQueueRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println("--------------------");
        System.out.println(Thread.currentThread().getName());
        System.out.println("---------------------");
    }
}

运行结果:

before thread pool execute linked size is :0
--------------------
pool-1-thread-1
---------------------
--------------------
pool-1-thread-3
---------------------
--------------------
pool-1-thread-3
---------------------
after thread pool execute linked size is :2
thread pool size is:3
--------------------
pool-1-thread-2
---------------------
--------------------
pool-1-thread-1
---------------------

b.当Runnable的数量大于maximumPoolSize与阻塞队列的和

package com.springboot.thread;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadQueueTest {
    public static void main(String[] args) {
        ArrayBlockingQueue linked = new ArrayBlockingQueue(2);
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,3,1L, TimeUnit.SECONDS,linked);
        ThreadQueueRunnable runnable  = new ThreadQueueRunnable();
        System.out.println("before thread pool execute linked size is :"+linked.size());
        threadPoolExecutor.execute(runnable);
        threadPoolExecutor.execute(runnable);
        threadPoolExecutor.execute(runnable);
        threadPoolExecutor.execute(runnable);
        threadPoolExecutor.execute(runnable);
        threadPoolExecutor.execute(runnable);
        System.out.println("after thread pool execute linked size is :"+linked.size());
        System.out.println("thread pool size is:" + threadPoolExecutor.getPoolSize());
    }
}


class ThreadQueueRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println("--------------------");
        System.out.println(Thread.currentThread().getName());
        System.out.println("---------------------");
    }
}

运行结果:

Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task com.springboot.thread.ThreadQueueRunnable@58372a00 rejected from java.util.concurrent.ThreadPoolExecutor@4dd8dc3[Running, pool size = 3, active threads = 3, queued tasks = 2, completed tasks = 0]
before thread pool execute linked size is :0
--------------------
pool-1-thread-1
---------------------
--------------------
pool-1-thread-1
---------------------
--------------------
pool-1-thread-1
---------------------
--------------------
pool-1-thread-2
---------------------
--------------------
pool-1-thread-3
---------------------
	at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
	at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
	at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)
	at com.springboot.thread.ThreadQueueTest.main(ThreadQueueTest.java:18)

总结一下:当我们使用ArrayBlockingQueue时,当runnable的数量小于等于线程池的大小与队列的和时,会先将部分runnable存到线程池中立刻开始执行,将剩余的runnable存入阻塞队列中。当runnable的数量大于线程池的数量与阻塞队列之和时会将线程池+阻塞队列数量的runnable执行,并抛出RejectedExecutionException,使用LinkedBlockingDeque时同理

(LinkedBlockingQueue和LinkedBlockingDeque分析:参考  https://blog.csdn.net/anLA_/article/details/79027867

2.使用SynchronousQueue 

  a.当Runnable的数量小于等于maximumPoolSize

package com.springboot.thread;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadQueueTest {
    public static void main(String[] args) {
        //ArrayBlockingQueue linked = new ArrayBlockingQueue(2);
        SynchronousQueue linked = new SynchronousQueue();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,3,1L, TimeUnit.SECONDS,linked);
        ThreadQueueRunnable runnable  = new ThreadQueueRunnable();
        System.out.println("before thread pool execute linked size is :"+linked.size());
        threadPoolExecutor.execute(runnable);
        threadPoolExecutor.execute(runnable);
        threadPoolExecutor.execute(runnable);
        //threadPoolExecutor.execute(runnable);
        System.out.println("after thread pool execute linked size is :"+linked.size());
        System.out.println("thread pool size is:" + threadPoolExecutor.getPoolSize());
    }
}


class ThreadQueueRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println("--------------------");
        System.out.println(Thread.currentThread().getName());
        System.out.println("---------------------");
    }
}

运行结果:

before thread pool execute linked size is :0
after thread pool execute linked size is :0
thread pool size is:3
--------------------
pool-1-thread-1
---------------------
--------------------
pool-1-thread-3
---------------------
--------------------
pool-1-thread-2
---------------------

b.当Runnable的数量大于maximumPoolSize

package com.springboot.thread;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadQueueTest {
    public static void main(String[] args) {
        //ArrayBlockingQueue linked = new ArrayBlockingQueue(2);
        SynchronousQueue linked = new SynchronousQueue();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,3,1L, TimeUnit.SECONDS,linked);
        ThreadQueueRunnable runnable  = new ThreadQueueRunnable();
        System.out.println("before thread pool execute linked size is :"+linked.size());
        threadPoolExecutor.execute(runnable);
        threadPoolExecutor.execute(runnable);
        threadPoolExecutor.execute(runnable);
        threadPoolExecutor.execute(runnable);
        System.out.println("after thread pool execute linked size is :"+linked.size());
        System.out.println("thread pool size is:" + threadPoolExecutor.getPoolSize());
    }
}


class ThreadQueueRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println("--------------------");
        System.out.println(Thread.currentThread().getName());
        System.out.println("---------------------");
    }
}

运行结果:

Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task com.springboot.thread.ThreadQueueRunnable@4dd8dc3 rejected from java.util.concurrent.ThreadPoolExecutor@6d03e736[Running, pool size = 3, active threads = 3, queued tasks = 0, completed tasks = 0]
	at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
	at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
	at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)
	at com.springboot.thread.ThreadQueueTest.main(ThreadQueueTest.java:18)
before thread pool execute linked size is :0
--------------------
pool-1-thread-1
---------------------
--------------------
pool-1-thread-3
---------------------
--------------------
pool-1-thread-2
---------------------

总结一下:当我们使用同步阻塞队列时,同步阻塞队列没有大小,当runnable的数量小于等于线程池的大小时每执行一次 threadPoolExecutor.execute(runnable);线程池的大小会加1,当超过线程池的的大时不再执行多余的任务并抛出RejectedExecutionException异常。

补代码:

package com.springboot.thread;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadQueueTest {
    public static void main(String[] args) {
        //ArrayBlockingQueue linked = new ArrayBlockingQueue(2);
        SynchronousQueue linked = new SynchronousQueue();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,3,1L, TimeUnit.SECONDS,linked);
        ThreadQueueRunnable runnable  = new ThreadQueueRunnable();
        System.out.println("before thread pool execute linked size is :"+linked.size());
        System.out.println("thread pool size is:" + threadPoolExecutor.getPoolSize());
        threadPoolExecutor.execute(runnable);
        threadPoolExecutor.execute(runnable);
        //threadPoolExecutor.execute(runnable);
        System.out.println("thread pool size is:" + threadPoolExecutor.getPoolSize());
        threadPoolExecutor.execute(runnable);
        System.out.println("after thread pool execute linked size is :"+linked.size());
        System.out.println("thread pool size is:" + threadPoolExecutor.getPoolSize());
    }
}


class ThreadQueueRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println("--------------------");
        System.out.println(Thread.currentThread().getName());
        System.out.println("---------------------");
    }
}

运行结果:

before thread pool execute linked size is :0
thread pool size is:0
thread pool size is:2
after thread pool execute linked size is :0
--------------------
pool-1-thread-2
---------------------
thread pool size is:3
--------------------
pool-1-thread-3
---------------------
--------------------
pool-1-thread-1
---------------------

 

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java线程池是一种用于管理和复用线程的机制,它可以提高多线程程序的性能和效率。在Java中,线程池由ThreadPoolExecutor类实现,通过设置不同的参数可以对线程池的行为进行调整。 以下是Java线程池的一些常用参数及其解释: 1. corePoolSize(核心线程数):线程池中始终保持的活动线程数,即使它们处于空闲状态。当有新任务提交时,如果活动线程数小于corePoolSize,则会创建新线程来处理任务。 2. maximumPoolSize(最大线程数):线程池中允许存在的最大线程数。当活动线程数达到maximumPoolSize并且工作队列已满时,新任务将会被拒绝。 3. keepAliveTime(线程空闲时间):当线程池中的线程数量超过corePoolSize时,多余的空闲线程在等待新任务到来时的最长等待时间。超过这个时间,空闲线程将被终止。 4. unit(时间单位):keepAliveTime的时间单位,可以是秒、毫秒、微秒等。 5. workQueue(工作队列):用于存储等待执行的任务的阻塞队列。常见的工作队列有ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue等。 6. threadFactory(线程工厂):用于创建新线程的工厂类。可以自定义线程的名称、优先级等属性。 7. handler(拒绝策略):当线程池无法接受新任务时的处理策略。常见的拒绝策略有AbortPolicy(默认,抛出RejectedExecutionException异常)、CallerRunsPolicy(由调用线程执行任务)、DiscardPolicy(直接丢弃任务)和DiscardOldestPolicy(丢弃最旧的任务)。 这些参数可以根据实际需求进行调整,以达到最佳的线程池性能和资源利用率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值