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 &lt; <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&lt;Runnable&gt;(<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&lt;<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.


About Pankaj

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.

ThreadPoolExecutor – Java Thread Pool Example(如何使用Executor框架创建一个线程池)的更多相关文章

  1. 【Java 并发】Executor框架机制与线程池配置使用

    [Java 并发]Executor框架机制与线程池配置使用 一,Executor框架Executor框架便是Java 5中引入的,其内部使用了线程池机制,在java.util.cocurrent 包下 ...

  2. ThreadPoolExecutor – Java Thread Pool Example

    https://www.journaldev.com/1069/threadpoolexecutor-java-thread-pool-example-executorservice   Java t ...

  3. ThreadPoolExecutor – Java Thread Pool Example(java线程池创建和使用)

    Java thread pool manages the pool of worker threads, it contains a queue that keeps tasks waiting to ...

  4. 创建一个线程池(java)

    private ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("billService-poo ...

  5. java并发编程(十七)Executor框架和线程池

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17465497   Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动 ...

  6. 二 Java利用等待/通知机制实现一个线程池

    接着上一篇博客的 一Java线程的等待/通知模型 ,没有看过的建议先看一下.下面我们用等待通知机制来实现一个线程池 线程的任务就以打印一行文本来模拟耗时的任务.主要代码如下: 1  定义一个任务的接口 ...

  7. Java并发(基础知识)—— Executor框架及线程池

    在Java并发(基础知识)—— 创建.运行以及停止一个线程中讲解了两种创建线程的方式:直接继承Thread类以及实现Runnable接口并赋给Thread,这两种创建线程的方式在线程比较少的时候是没有 ...

  8. Java多线程01(Thread类、线程创建、线程池)

    Java多线程(Thread类.线程创建.线程池) 第一章 多线程 1.1 多线程介绍 1.1.1 基本概念 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于 ...

  9. java基础(26):Thread、线程创建、线程池

    1. 多线程 1.1 多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念. 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并 ...

随机推荐

  1. 父类与子类的virtual

    父类加了virtual,子类不需要加virtual,多余.加了也不会报错. 父类中不是virtual,子类是virtual,那么父类中的不是虚函数,子类及子子类的派生类中该函数才是虚函数

  2. android与C# WebService基于ksoap通信(C#篇)

    1.打开VS 2013新建项目>>ASP.NET空WEB应用程序(我用的是.net 4.0) 2.在刚建立的项目上加入新建项(WebService) 这时TestService的代码例如以 ...

  3. JS中的onload与jQuery中的ready差别

    jQuery的运行机制(onload与ready的差别) 结论得出前自行測试: 为了測试是否真如所说的那样,所以在页面插入了20000张照片,照片数量少得不出什么结论,所以改用console.log( ...

  4. Android学习笔记(三)

    ContentProvider简单介绍 ContentProvider是不同应用程序之间进行数据交换的标准API,当一个应用程序须要把自己的数据暴露给其它程序使用时.该应用程序便可通过提供Conten ...

  5. Json技术

    JSON语法是一种用于传输和生成数据的协定,很类似于C家族的语言,所以很容易被C家族的语言所解析.对象:对象包含再{}之间属性:采用Key-Value对来表示.属性之间使用逗号分开.  string ...

  6. 10.cocos2d坐标系

    一.笛卡儿坐标系 OpenGl坐标系为笛卡儿右手系.x向右,y向上,z向外.在cocos2d-lua中坐标系原点在屏幕的左下角,x向右,y向上,z则是指的zorder(层级). 二.世界坐标系,本地坐 ...

  7. Linux智能手机安全策略研究

    Linux智能手机安全策略研究 http://www.zdnet.com.cn    本文是继从“窃听门”事件解读手机Rootkit攻击(http://chenguang.blog.51cto.com ...

  8. OpenCV —— 矩阵操作

    多通道的矩阵 —— 通道是连续的!! 要将指向该数据类型的指针移动到下一通道,我们只需要将其增加1.如果想访问下一个“像素”或者元素集,则需要一定的偏移量 矩阵的step元素是矩阵中行的长度,单位为字 ...

  9. Centos 7 JDK验证 解决java -version 报错: bash: /home/jdk1.8.0_161/bin/java: Permission denied

    2.vim /etc/profile  编辑profile  文件,在里面添加: #set java enviroment JAVA_HOME=/usr/java/jdk1.8.0_144 JRE_H ...

  10. 平衡树之RB-tree

    #include <memory> template<class T> struct rb_node { T key; bool color;//true red | fals ...