ThreadPoolExecutor – Java Thread Pool Example(java线程池创建和使用)
Java thread pool manages the pool of worker threads, it contains a queue that keeps tasks waiting to get executed. We can use ThreadPoolExecutor to create thread pool in java.

Java thread pool manages the collection of Runnable threads and worker threads execute Runnable from the queue. java.util.concurrent.Executors provide implementation of java.util.concurrent.Executor interface to create the thread pool in java. Let’s write a simple program to explain it’s working.
First we need to have a Runnable class, named WorkerThread.java
Copy
package com.journaldev.threadpool;
public class WorkerThread implements Runnable {
<span class="hljs-keyword">private</span> String command;
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">WorkerThread</span><span class="hljs-params">(String s)</span></span>{
<span class="hljs-keyword">this</span>.command=s;
}
<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span><span class="hljs-params">()</span> </span>{
System.out.println(Thread.currentThread().getName()+<span class="hljs-string">" Start. Command = "</span>+command);
processCommand();
System.out.println(Thread.currentThread().getName()+<span class="hljs-string">" End."</span>);
}
<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">processCommand</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">try</span> {
Thread.sleep(<span class="hljs-number">5000</span>);
} <span class="hljs-keyword">catch</span> (InterruptedException e) {
e.printStackTrace();
}
}
<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">toString</span><span class="hljs-params">()</span></span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.command;
}
}
ExecutorService Example
Here is the test program class SimpleThreadPool.java, where we are creating fixed thread pool from Executors framework.
Copy
package com.journaldev.threadpool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SimpleThreadPool {
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
ExecutorService executor = Executors.newFixedThreadPool(<span class="hljs-number">5</span>);
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-number">10</span>; i++) {
Runnable worker = <span class="hljs-keyword">new</span> WorkerThread(<span class="hljs-string">""</span> + i);
executor.execute(worker);
}
executor.shutdown();
<span class="hljs-keyword">while</span> (!executor.isTerminated()) {
}
System.out.println(<span class="hljs-string">"Finished all threads"</span>);
}
}
In above program, we are creating fixed size thread pool of 5 worker threads. Then we are submitting 10 jobs to this pool, since the pool size is 5, it will start working on 5 jobs and other jobs will be in wait state, as soon as one of the job is finished, another job from the wait queue will be picked up by worker thread and get’s executed.
Here is the output of the above program.
Copy
pool-1-thread-2 Start. Command = 1
pool-1-thread-4 Start. Command = 3
pool-1-thread-1 Start. Command = 0
pool-1-thread-3 Start. Command = 2
pool-1-thread-5 Start. Command = 4
pool-1-thread-4 End.
pool-1-thread-5 End.
pool-1-thread-1 End.
pool-1-thread-3 End.
pool-1-thread-3 Start. Command = 8
pool-1-thread-2 End.
pool-1-thread-2 Start. Command = 9
pool-1-thread-1 Start. Command = 7
pool-1-thread-5 Start. Command = 6
pool-1-thread-4 Start. Command = 5
pool-1-thread-2 End.
pool-1-thread-4 End.
pool-1-thread-3 End.
pool-1-thread-5 End.
pool-1-thread-1 End.
Finished all threads
The output confirms that there are five threads in the pool named from “pool-1-thread-1” to “pool-1-thread-5” and they are responsible to execute the submitted tasks to the pool.
ThreadPoolExecutor Example
Executors class provide simple implementation of ExecutorService using ThreadPoolExecutor but ThreadPoolExecutor provides much more feature than that. We can specify the number of threads that will be alive when we create ThreadPoolExecutor instance and we can limit the size of thread pool and create our own RejectedExecutionHandler implementation to handle the jobs that can’t fit in the worker queue.
Here is our custom implementation of RejectedExecutionHandler interface.
Copy
package com.journaldev.threadpool;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
public class RejectedExecutionHandlerImpl implements RejectedExecutionHandler {
<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">rejectedExecution</span><span class="hljs-params">(Runnable r, ThreadPoolExecutor executor)</span> </span>{
System.out.println(r.toString() + <span class="hljs-string">" is rejected"</span>);
}
}
ThreadPoolExecutor provides several methods using which we can find out the current state of executor, pool size, active thread count and task count. So I have a monitor thread that will print the executor information at certain time interval.
Copy
package com.journaldev.threadpool;
import java.util.concurrent.ThreadPoolExecutor;
public class MyMonitorThread implements Runnable
{
private ThreadPoolExecutor executor;
private int seconds;
private boolean run=true;
public MyMonitorThread(ThreadPoolExecutor executor, int delay)
{
this.executor = executor;
this.seconds=delay;
}
public void shutdown(){
this.run=false;
}
@Override
public void run()
{
while(run){
System.out.println(
String.format("[monitor] [%d/%d] Active: %d, Completed: %d, Task: %d, isShutdown: %s, isTerminated: %s",
this.executor.getPoolSize(),
this.executor.getCorePoolSize(),
this.executor.getActiveCount(),
this.executor.getCompletedTaskCount(),
this.executor.getTaskCount(),
this.executor.isShutdown(),
this.executor.isTerminated()));
try {
Thread.sleep(seconds*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Here is the thread pool implementation example using ThreadPoolExecutor.
Copy
package com.journaldev.threadpool;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class WorkerPool {
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String args[])</span> <span class="hljs-keyword">throws</span> InterruptedException</span>{
<span class="hljs-comment">//RejectedExecutionHandler implementation</span>
RejectedExecutionHandlerImpl rejectionHandler = <span class="hljs-keyword">new</span> RejectedExecutionHandlerImpl();
<span class="hljs-comment">//Get the ThreadFactory implementation to use</span>
ThreadFactory threadFactory = Executors.defaultThreadFactory();
<span class="hljs-comment">//creating the ThreadPoolExecutor</span>
ThreadPoolExecutor executorPool = <span class="hljs-keyword">new</span> ThreadPoolExecutor(<span class="hljs-number">2</span>, <span class="hljs-number">4</span>, <span class="hljs-number">10</span>, TimeUnit.SECONDS, <span class="hljs-keyword">new</span> ArrayBlockingQueue<Runnable>(<span class="hljs-number">2</span>), threadFactory, rejectionHandler);
<span class="hljs-comment">//start the monitoring thread</span>
MyMonitorThread monitor = <span class="hljs-keyword">new</span> MyMonitorThread(executorPool, <span class="hljs-number">3</span>);
Thread monitorThread = <span class="hljs-keyword">new</span> Thread(monitor);
monitorThread.start();
<span class="hljs-comment">//submit work to the thread pool</span>
<span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i<<span class="hljs-number">10</span>; i++){
executorPool.execute(<span class="hljs-keyword">new</span> WorkerThread(<span class="hljs-string">"cmd"</span>+i));
}
Thread.sleep(<span class="hljs-number">30000</span>);
<span class="hljs-comment">//shut down the pool</span>
executorPool.shutdown();
<span class="hljs-comment">//shut down the monitor thread</span>
Thread.sleep(<span class="hljs-number">5000</span>);
monitor.shutdown();
}
}
Notice that while initializing the ThreadPoolExecutor, we are keeping initial pool size as 2, maximum pool size to 4 and work queue size as 2. So if there are 4 running tasks and more tasks are submitted, the work queue will hold only 2 of them and rest of them will be handled by RejectedExecutionHandlerImpl.
Here is the output of above program that confirms above statement.
Copy
pool-1-thread-1 Start. Command = cmd0
pool-1-thread-4 Start. Command = cmd5
cmd6 is rejected
pool-1-thread-3 Start. Command = cmd4
pool-1-thread-2 Start. Command = cmd1
cmd7 is rejected
cmd8 is rejected
cmd9 is rejected
[monitor] [0/2] Active: 4, Completed: 0, Task: 6, isShutdown: false, isTerminated: false
[monitor] [4/2] Active: 4, Completed: 0, Task: 6, isShutdown: false, isTerminated: false
pool-1-thread-4 End.
pool-1-thread-1 End.
pool-1-thread-2 End.
pool-1-thread-3 End.
pool-1-thread-1 Start. Command = cmd3
pool-1-thread-4 Start. Command = cmd2
[monitor] [4/2] Active: 2, Completed: 4, Task: 6, isShutdown: false, isTerminated: false
[monitor] [4/2] Active: 2, Completed: 4, Task: 6, isShutdown: false, isTerminated: false
pool-1-thread-1 End.
pool-1-thread-4 End.
[monitor] [4/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false
[monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false
[monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false
[monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false
[monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false
[monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false
[monitor] [0/2] Active: 0, Completed: 6, Task: 6, isShutdown: true, isTerminated: true
[monitor] [0/2] Active: 0, Completed: 6, Task: 6, isShutdown: true, isTerminated: true
Notice the change in active, completed and total completed task count of the executor. We can invoke shutdown() method to finish execution of all the submitted tasks and terminate the thread pool.
If you want to schedule a task to run with delay or periodically then you can use ScheduledThreadPoolExecutor class. Read more about them at Java Schedule Thread Pool Executor.
If you have come this far, it means that you liked what you are reading. Why not reach little more and connect with me directly on Google Plus, Facebook or Twitter. I would love to hear your thoughts and opinions on my articles directly. Recently I started creating video tutorials too, so do check out my videos on Youtube.
About Pankaj
ThreadPoolExecutor – Java Thread Pool Example(java线程池创建和使用)的更多相关文章
- Smart Thread Pool (智能线程池)
STPStartInfo stp = new STPStartInfo(); stp.DisposeOfStateObjects = true; stp.CallToPostExecute = ...
- Java并发(四)线程池使用
上一篇博文介绍了线程池的实现原理,现在介绍如何使用线程池. 目录 一.创建线程池 二.向线程池提交任务 三.关闭线程池 四.合理配置线程池 五.线程池的监控 线程池创建规范 一.创建线程池 我们可以通 ...
- ThreadPoolExecutor – Java Thread Pool Example(如何使用Executor框架创建一个线程池)
Java thread pool manages the pool of worker threads, it contains a queue that keeps tasks waiting to ...
- Java线程池ThreadPoolExecutor使用和分析(三) - 终止线程池原理
相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...
- ThreadPoolExecutor – Java Thread Pool Example
https://www.journaldev.com/1069/threadpoolexecutor-java-thread-pool-example-executorservice Java t ...
- java多线程(四)-自定义线程池
当我们使用 线程池的时候,可以使用 newCachedThreadPool()或者 newFixedThreadPool(int)等方法,其实我们深入到这些方法里面,就可以看到它们的是实现方式是这样的 ...
- Java并发(六)线程池监控
目录 一.线程池监控参数 二.线程池监控类 三.注意事项 在上一篇博文中,我们介绍了线程池的基本原理和使用方法.了解了基本概念之后,我们可以使用 Executors 类创建线程池来执行大量的任务,使用 ...
- Java并发(三)线程池原理
Java中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序都可以使用线程池.在开发过程中,合理地使用线程池能够带来3个好处. 1. 降低资源消耗.通过重复利用已创建的线程降低线程 ...
- java多线程系列六、线程池
一. 线程池简介 1. 线程池的概念: 线程池就是首先创建一些线程,它们的集合称为线程池. 2. 使用线程池的好处 a) 降低资源的消耗.使用线程池不用频繁的创建线程和销毁线程 b) 提高响应速度,任 ...
随机推荐
- 什么是string interning(字符串驻留)以及python中字符串的intern机制
Incomputer science, string interning is a method of storing only onecopy of each distinct string val ...
- CSS Text
http://www.runoob.com/css/css-text.html 文本颜色 颜色属性被用来设置文字的颜色. 颜色是通过CSS最经常的指定: 十六进制值 - 如: #FF0000 一个RG ...
- Onvif开发之客户端鉴权获取参数篇
前面一篇已经介绍了客户端如何发些设备,下面这篇简单介绍下在发现设备后,如何通过ONVIF协议来获取设备的相关参数 ONVIF中不管是客户端还是设备端,最先实现的接口都是关于能力的那个接口,在客户端实现 ...
- js全局的解析与执行过程
先看下面实例的执行结果: alert(a);//undefined alert(b);//报错 alert(f);//输出f函数字符串 alert(g);//undefined var a = 1; ...
- log大全
http://www.iconfont.cn/search/index?q=%E6%88%91%E7%9A%84&page=3
- 压状态bfs
一般地图很小,状态不多,可以装压或者hash,构造压缩或hash的函数,构造还原地图的函数,然后就无脑bfs(感觉就是SPFA) 题目: 1.玩具游戏:二进制压缩状态 #include<cstd ...
- linux系统下的/proc目录介绍
1. /proc目录 Linux 内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构.改变内核设置的机制.proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间.它以 ...
- 如何优雅的写UI——(3)添加MFC选项卡
窗体创建完成,接下来我们讲讲控件的使用 首先在CFormView窗体下选项卡的成员变量,这里我选择MFC下的选项卡类库:CMFCTabCtrl class CtabView : public CFor ...
- gdal读写图像分块处理
转自赵文原文 gdal读写图像分块处理(精华版) Review: 用gdal,感觉还不如直接用C++底层函数对遥感数据进行处理.因为gdal进行太多封装,如果你仅仅只是Geotif等格式进行处理,IO ...
- 计算机视觉(ComputerVision, CV)相关领域的站点链接
关于计算机视觉(ComputerVision, CV)相关领域的站点链接,当中有CV牛人的主页.CV研究小组的主页,CV领域的paper,代码.CV领域的最新动态.国内的应用情况等等. (1)goog ...