This article is roughly divided into 10 parts, which are
1. Thread pool workflow
2. Thread pool constructor
3. Thread pool parameters
4. Use the thread pool example
5. What is a thread factory
6. What is the rejection strategy
7. Common blocking queues
8. Common thread pool usage
9. Extend the thread pool method
10. Digression
We know that creating a thread and destroying a thread in a computer are both very resource-intensive operations, and there’s an idea called pooling, which means we create a pool, we do all the resource-intensive operations ahead of time, and then we all use what we’ve created together, and then we destroy it. Save the use of a create a, destroy a, this resource – consuming operation.
I. How thread pools work
This is the idea of a thread pool, whose basic workflow is shown in the figure below
The following figure shows the basic thread pool workflow
So what are his core threads, his task queues, these? How do you set it?
We’ll start with the code. Let’s first look at the thread pool constructor code
Thread pool constructor
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
Copy the code
There are actually four constructors for ThreadPoolExecutor, but the bottom line is the seven-argument constructor, so it’s good to understand this one. Here’s the bottom line implementation of the other constructors
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}
Copy the code
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
Copy the code
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
Copy the code
The default rejection policy is
private static final RejectedExecutionHandler defaultHandler =
new AbortPolicy();
Copy the code
Of these constructors
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
Copy the code
That’s the constructor for those seven parameters
Mentally? It doesn’t matter. Let’s analyze each of the seven parameters one by one
3. Thread pool parameters
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
Copy the code
1. The first parameter corePoolSize represents the number of core threads in the thread pool
2. The second parameter, maximumPoolSize, represents the maximum number of threads in the pool (core + non-core).
3. The third parameter, keepAliveTime, represents the idle lifetime of the pool’s non-core threads
4. The fourth argument, unit, represents the unit of idle lifetime for the non-core threads of the thread pool
5. The fifth parameter workQueue represents the task blocking queue for this thread pool. There are several common blocking queues in the JDK
- ArrayBlockingQueue: Bounded blocking queue based on array structure
- LinkedBlockingQueue: Is a blocking queue based on a linked list structure
- SynchronousQueue: a SynchronousQueue that stores only one task and waits to insert it (if there are elements in the queue) and to retrieve it (if there are no elements)
- PriorityBlockingQueue: Priority queue. Elements entering the queue are sorted in order of priority
Suggestion: It is recommended to use a bounded queue. If there are too many tasks in an unbounded queue, it may cause an OOM result
6. The sixth argument, threadFactory (customizable), represents the factory that creates threads for the pool. There are two types of factory
- Executors. PrivilegedThreadFactory () to use access to create a thread of access control.
- Executors. DefaultThreadFactory () will create a thread group and the default priority threads
7. The seventh parameter, handler (which can be customized), represents the saturation policy for the thread pool to deny processing tasks. The JDK provides four by default
- new ThreadPoolExecutor.AbortPolicy(); Direct throw exception
- new ThreadPoolExecutor.CallerRunsPolicy(); Process the passed task in the current caller’s thread
- new ThreadPoolExecutor.DiscardOldestPolicy(); Discard the oldest task and add the incoming task to the blocking queue
- new ThreadPoolExecutor.DiscardPolicy(); Do nothing, just throw away the task that was handed to you
Use thread pool example
With the basic concepts covered, let’s look at a small example of using thread pools to process tasks
First, let’s create a task class
public class Task implements Runnable {
private String taskName;
public Task(String taskName) {
this.taskName = taskName;
}
@Override
public void run(a) {
try {
// Simulate the time spent for each task
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String name = Thread.currentThread().getName();
System.out.println("This is xhJaver, the current thread name of the thread pool series is" + name+"Dealt with"+ taskName+" 任务"); }}Copy the code
Let’s look at the test class again
public class Demo1 {
public static void main(String[] args) {
// Block the queue and set the maximum number of blocked tasks to 10
BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable> (10);
// Thread factory
ThreadFactory threadFactory = Executors.defaultThreadFactory();
When the maximum worker of the thread pool is full and the blocking queue is full, the reject policy handles the rest of the work
ThreadPoolExecutor.AbortPolicy abortPolicy = new ThreadPoolExecutor.AbortPolicy();
// Create a thread pool. The number of core threads is 5. The maximum number of threads is 10
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5.10.60L,
TimeUnit.SECONDS, blockingQueue, threadFactory, abortPolicy
);
for (int i=0; i<10; i++){// Create 10 tasks. If >20 tasks are created, all tasks outside 20 will be handled by the denial policy
Task task = new Task("task" + i);
// Let's create our own thread pool to run these tasks
threadPoolExecutor.execute(task);
}
// Remember to close the thread poolthreadPoolExecutor.shutdown(); }}Copy the code
The output is
Here is xhJaver, the thread pool series current thread name is pool-1-thread-1This is xhJaver, thread pool series. The current thread name is pool-1-thread-2This is xhJaver. The current thread name of the thread pool series is pool-1-thread-3This is xhJaver. The current thread name of the thread pool series is pool-1-thread-4This is xhJaver. The current thread name of the thread pool series is pool-1-thread-5This is xhJaver. The current thread name of the thread pool series is pool-1-thread-1This is xhJaver, thread pool series. The current thread name is pool-1-thread-2This is xhJaver, thread pool series. The current thread name is pool-1-thread-5This is xhJaver, thread pool series. The current thread name is pool-1-thread-4This is xhJaver, thread pool series. The current thread name is pool-1-thread-3The Task7 task is processedCopy the code
What is a thread factory?
Thread factory thread factory, what is a thread factory? The factory that creates the thread must have a name, as shown in the example above. The name of the thread is pool-1-thread-3 and so on.
First, you implement the Thread newThread(Runnable r) method in the ThreadFactory interface, passing in a task that returns a custom Thread, as shown below
public class DIYThreadFactory implements ThreadFactory {
private AtomicInteger atomicInteger;
public DIYThreadFactory( AtomicInteger atomicInteger){
this.atomicInteger = atomicInteger;
}
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setName("xhJaver-thread-"+atomicInteger.getAndIncrement());
returnthread; }}Copy the code
This custom thread factory is then passed in when used
public static void main(String[] args) {
// Block the queue and set the maximum number of blocked tasks to 10
BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable> (10);
// Create a thread-safe counter
AtomicInteger atomicInteger = new AtomicInteger();
// Custom thread factory
ThreadFactory threadFactory = new DIYThreadFactory(atomicInteger);
When the maximum worker of the thread pool is full and the blocking queue is full, the reject policy handles the rest of the work
ThreadPoolExecutor.AbortPolicy abortPolicy = new ThreadPoolExecutor.AbortPolicy();
// Create a thread pool. The number of core threads is 5. The maximum number of threads is 10
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5.10.60L,
TimeUnit.SECONDS, blockingQueue, threadFactory, abortPolicy
);
for (int i=0; i<10; i++){// Create 10 tasks. If >20 tasks are created, all tasks outside 20 will be handled by the denial policy
Task task = new Task("task" + i);
// Let's create our own thread pool to run these tasks
threadPoolExecutor.execute(task);
}
// Remember to close the thread pool
threadPoolExecutor.shutdown();
}
Copy the code
The output is
Here is xhJaver, the current thread name of the thread pool series is xhJaver-thread-0The current thread name of the thread pool series is xhJaver-thread-1The current thread name of the thread pool series is xhJaver-thread-4The current thread name of the thread pool series is xhJaver-thread-3The current thread name of the thread pool series is xhJaver-thread-2The current thread name of the thread pool series is xhJaver-thread-0This is xhJaver, and the current thread name of the thread pool series is xhJaver-thread-1The current thread name of the thread pool series is xhJaver-thread-2The current thread name of the thread pool series is xhJaver-thread-3The current thread name of the thread pool series is xhJaver-thread-4The Task7 task is processedCopy the code
I also learned to customize the thread factory, but the custom name is useful, of course, to troubleshoot problems! Define the thread name as the name related to your business, when the error will be convenient troubleshooting.
What is the rejection strategy
Thread factories can be customized, but can rejection policies be customized? RejectedExecutionHandler (); rejectedExecution ()
public class DIYRejectedHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
// Record operations such as logs
System.out.println("This is a task that xhJaver cannot handle."+r.toString()+"Current thread name is"+Thread.currentThread().getName()); }}Copy the code
This custom rejection policy is then passed in when used
public static void main(String[] args) {
// Block the queue and set the maximum number of blocked tasks to 10
BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable> (10);
// Create a thread-safe counter
AtomicInteger atomicInteger = new AtomicInteger();
// Custom thread factory
ThreadFactory threadFactory = new DIYThreadFactory(atomicInteger);
When the maximum worker thread in the thread pool is full and the blocking queue is full, the reject policy handles the rest of the work
DIYRejectedHandler diyRejectedHandler = new DIYRejectedHandler();
// Create a thread pool. The number of core threads is 5. The maximum number of threads is 10
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5.10.60L,
TimeUnit.SECONDS, blockingQueue, threadFactory, diyRejectedHandler
);
for (int i=0; i<30; i++){// Create 10 tasks. If >20 tasks are created, all tasks outside 20 will be handled by the denial policy
Task task = new Task("task" + i);
// Let's create our own thread pool to run these tasks
threadPoolExecutor.execute(task);
}
// Remember to close the thread pool
threadPoolExecutor.shutdown();
}
Copy the code
The output is
This is a Task that xhJaver cannot handle Task{taskName='task20'} The current thread name is main. This is a Task that xhJaver cannot handle'task21'} The current thread name is main. This is a Task that xhJaver cannot handle'task22'} The current thread name is main. This is a Task that xhJaver cannot handle'task23'} The current thread name is main. This is a Task that xhJaver cannot handle'task24'} The current thread name is main. This is a Task that xhJaver cannot handle'task25'} The current thread name is main. This is a Task that xhJaver cannot handle'task26'} The current thread name is main. This is a Task that xhJaver cannot handle'task27'} The current thread name is main. This is a Task that xhJaver cannot handle'task28'} The current thread name is main. This is a Task that xhJaver cannot handle'task29'} The current thread name is xhJaver, and the current thread name is xhJaver-thread-5The current thread name of the thread pool series is xhJaver-thread-4The current thread name of the thread pool series is xhJaver-thread-3The current thread name of the thread pool series is xhJaver-thread-2The current thread name of the thread pool series is xhJaver-thread-1The current thread name of the thread pool series is xhJaver-thread-0The current thread name of the thread pool series is xhJaver-thread-9The current thread name of the thread pool series is xhJaver-thread-8The current thread name of the thread pool series is xhJaver-thread-7The current thread name of the thread pool series is xhJaver-thread-6The current thread name of the thread pool series is xhJaver-thread-4The current thread name of the thread pool series is xhJaver-thread-5This is xhJaver, and the current thread name of the thread pool series is xhJaver-thread-3The current thread name of the thread pool series is xhJaver-thread-2The current thread name of the thread pool series is xhJaver-thread-1The current thread name of the thread pool series is xhJaver-thread-0The current thread name of the thread pool series is xhJaver-thread-9The current thread name of the thread pool series is xhJaver-thread-8The current thread name of the thread pool series is xhJaver-thread-7The current thread name of the thread pool series is xhJaver-thread-6The TASK14 task is processedCopy the code
Common blocking queues and attention points
Because there’s a lot to know about blocking queues, we’ll start with blocking queues in its own right, starting with a few common ones
LinkedBlockingQueue is an unbounded queue based on a linked list. It has only one element inside. It blocks if an element is not removed from the queue. Fetching an element is blocked if there are no elements in the queue until an element is inserted.
To match the thread pool use the following, first create the task class
public class Task implements Runnable {
private String taskName;
public Task(String taskName) {
this.taskName = taskName;
}
@Override
public String toString(a) {
return "Task{" +
"taskName='" + taskName + '\' ' +
'} ';
}
@Override
public void run(a) {
try {
// Simulate the time spent for each task
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String name = Thread.currentThread().getName();
System.out.println("This is xhJaver, the current thread name of the thread pool series is" + name+"Dealt with"+ taskName+" 任务"); }}Copy the code
Then use the blocking queue
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i=0; i<10; i++){// Create ten tasks
Task task = new Task("task" + i);
// Go on a mission
executorService.execute(task);
}
// Remember to close the thread pool
executorService.shutdown();
}
Copy the code
The underlying use of newCachedThreadPool is SynchronousQueue
public static ExecutorService newCachedThreadPool(a) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
Copy the code
The output is
Here is xhJaver, the thread pool series current thread name is pool-1-thread-1This is xhJaver, thread pool series. The current thread name is pool-1-thread-2This is xhJaver. The current thread name of the thread pool series is pool-1-thread-5This is xhJaver. The current thread name of the thread pool series is pool-1-thread-4This is xhJaver. The current thread name of the thread pool series is pool-1-thread-3This is xhJaver. The current thread name of the thread pool series is pool-1-thread-6This is xhJaver, thread pool series. The current thread name is pool-1-thread-7This is xhJaver, thread pool series. The current thread name is pool-1-thread-10This is xhJaver, thread pool series. The current thread name is pool-1-thread-9This is xhJaver, thread pool series. The current thread name is pool-1-thread-8The Task7 task is processedCopy the code
As you can see, the thread pool creates ten threads to handle each of these ten tasks. Why? This is because, I simulate the processing time of each task is 1 s, when the task has found that blocking the queue again task has not been removed, is just to create non-core thread to handle this task, constantly to task, constantly create threads, so blocking queue with this match again thread pool set parameters, such as the total number of threads may lead to OOM for continuously create a thread.
Elements entering the queue are sorted by task priority. And the Comparable interface must be implemented.
Parameter: priorityTask – The object to be compared. Returns: a negative integer, zero, or positive integer depending on whether the object is less than, equal to, or greater than the specified object (the object to be compared).
Start by creating a task with a priority
public class PriorityTask implements Runnable , Comparable<PriorityTask>{
private String taskName;
// Priority, which is sorted by this number
private Integer priority;
public PriorityTask(Integer priority,String taskName) {
this.priority = priority;
this.taskName = taskName;
}
// If the return value of the compareTo method is -1, the order will consider that the passed task is larger than this task and will be sorted in descending order
// If the return value of the compareTo method is 1, the order will consider that the passed task is smaller than this task, and the order will be ascending
@Override
public int compareTo(PriorityTask priorityTask) {
//Integer.compare returns -1 to indicate that the priority of the passed task is smaller than the priority of the secondary task
// Integer.compare 0 the priority of the passed task is the same as the priority of the secondary task
//Integer.compare 1: the priority of the passed task is greater than the priority of the secondary task
return Integer.compare(priorityTask.priority,this.priority);
}
@Override
public void run(a) {
try {
// Simulate the time spent for each task
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String name = Thread.currentThread().getName();
System.out.println("This is xhJaver, the current thread name of the thread pool series is" + name+"Dealt with"+ taskName+" 任务");
}
@Override
public String toString(a) {
return "Task{" +
"taskName='" + taskName + '\' ' +
'} '; }}Copy the code
Comparison size code for Integer.compare
java
public static int compare(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
Copy the code
The test code
public static void main(String[] args) {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1.1.60L, TimeUnit.SECONDS,
new PriorityBlockingQueue());
for (int i=0; i<5; i++){// Create ten tasks
PriorityTask priorityTask = new PriorityTask(i,"task" + i);
// Go on a mission
threadPoolExecutor.execute(priorityTask);
}
for (int i=100; i>=95; i--){// Create ten tasks
PriorityTask priorityTask = new PriorityTask(i,"task" + i);
// Go on a mission
threadPoolExecutor.execute(priorityTask);
}
// Remember to close the thread pool
threadPoolExecutor.shutdown();
}
Copy the code
The output is
Here is xhJaver, the thread pool series current thread name is pool-1-thread-1This is xhJaver, thread pool series. The current thread name is pool-1-thread-1This is xhJaver, thread pool series. The current thread name is pool-1-thread-1This is xhJaver, thread pool series. The current thread name is pool-1-thread-1This is xhJaver, thread pool series. The current thread name is pool-1-thread-1This is xhJaver, thread pool series. The current thread name is pool-1-thread-1This is xhJaver, thread pool series. The current thread name is pool-1-thread-1This is xhJaver, thread pool series. The current thread name is pool-1-thread-1This is xhJaver. The current thread name of the thread pool series is pool-1-thread-1This is xhJaver. The current thread name of the thread pool series is pool-1-thread-1This is xhJaver. The current thread name of the thread pool series is pool-1-thread-1The task1 task is processedCopy the code
As you can see from the output, with the exception of the first one, the order of processing tasks is first processed according to the priority size
Eight, several common thread pools and points to note
They are the following
1.newFixedThreadPool
- Executors. NewFixedThreadPool (10) is its construction method
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
Copy the code
So, this FixedThreadPool has the same number of core threads as the maximum number of threads, so there are no non-core threads, and the lifetime parameter is invalid. It uses LinkedBlockingQueue, which is an unbounded queue. You can click on the source code to see that its default capacity is integer.max_value
public LinkedBlockingQueue(a) {
this(Integer.MAX_VALUE);
}
Copy the code
So what’s the problem with that? When the core threads are full, new tasks will be added to the blocking queue, but the memory is limited, so there may be OOM (OutOfMemory) issues
- Executors.newFixedThreadPool(10,Executors.defaultThreadFactory());
This constructor can be passed to the specified factory that created the thread
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
Copy the code
2.newCachedThreadPool
- Executors.newCachedThreadPool()
The way it’s constructed is
public static ExecutorService newCachedThreadPool(a) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
Copy the code
The default number of core threads is 0, the total thread size of the pool is Integer.MAX_VALUE, the blocking queue is SynchronousQueue, and the idle lifetime of non-core threads is 60 seconds. If a task is created, a non-core thread will be created to run the task. If another task is created while the task is running, a thread will be created to run the task
- Executors.newCachedThreadPool(Executors.defaultThreadFactory())
This constructor can be passed to the specified factory that created the thread
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
}
Copy the code
3.newSingleThreadExecutor
- Executors.newSingleThreadExecutor()
The way it’s constructed is
public static ExecutorService newSingleThreadExecutor(a) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1.1.0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
Copy the code
We can see that it has one core thread and one total thread. If there are no threads in the thread pool, a single thread will be created to execute the task. The rest of the tasks will be put into the unbounded blocking queue. This will also cause an OOM issue.
- Executors.newSingleThreadExecutor(Executors.defaultThreadFactory())
This constructor can be passed to the specified factory that created the thread
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1.1.0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}
Copy the code
Expand the thread pool
What? Can thread pools be expanded? ! ThreadPoolExecutor provides several methods inside the ThreadPoolExecutor function, including beforeExecute, afterExecute, and terminated methods. These three situations correspond to task start, task end, and thread pool closed, so we need to rewrite them. Without further comment, let’s look at the code
public static void main(String[] args) {
// Block the queue and set the maximum number of blocked tasks to 10
BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable> (10);
// Create a thread-safe counter
AtomicInteger atomicInteger = new AtomicInteger();
// Custom thread factory
ThreadFactory threadFactory = new DIYThreadFactory(atomicInteger);
When the maximum worker thread in the thread pool is full and the blocking queue is full, the reject policy handles the rest of the work
DIYRejectedHandler diyRejectedHandler = new DIYRejectedHandler();
// Create a thread pool. The number of core threads is 5. The maximum number of threads is 10
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5.10.60L,
TimeUnit.SECONDS, blockingQueue, threadFactory, diyRejectedHandler
){
@Override
protected void beforeExecute(Thread t, Runnable r) {
System.out.println("The current thread of xhJaver is"+t.getName()+"Get started on a task:"+r.toString());
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
if(t! =null){
System.out.println("The current thread of xhJaver is"+Thread.currentThread().getName() +"End of processing task:"+r.toString()+"The mistake is"+ t);
}
System.out.println("The current thread of xhJaver is"+Thread.currentThread().getName() +"End of processing task:"+r.toString()+"There is no error.");
}
@Override
protected void terminated(a) {
System.out.println("The current thread of xhJaver is"+Thread.currentThread().getName() +"Close the thread pool"); }};for (int i=0; i<21; i++){// Create 10 tasks. If >20 tasks are created, all tasks outside 20 will be handled by the denial policy
Task task = new Task("task" + i);
// Let's create our own thread pool to run these tasks
threadPoolExecutor.execute(task);
}
// Remember to close the thread pool
threadPoolExecutor.shutdown();
}
Copy the code
The output is
This is a Task that xhJaver cannot handle Task{taskName='task20'} The current thread name is main xhJaver. The current thread name is xhJaver-thread-7To start a Task: Task{taskName='task17'} xhJaver The current thread is xhJaver thread-6To start a Task: Task{taskName='task16'} xhJaver The current thread is xhJaver thread-9To start a Task: Task{taskName='task19'} xhJaver The current thread is xhJaver thread-4To start a Task: Task{taskName='task4'} xhJaver The current thread is xhJaver thread-8To start a Task: Task{taskName='task18'} xhJaver The current thread is xhJaver thread-2To start a Task: Task{taskName='task2'} xhJaver The current thread is xhJaver thread-3To start a Task: Task{taskName='task3'} xhJaver The current thread is xhJaver thread-5To start a Task: Task{taskName='task15'} xhJaver The current thread is xhJaver thread-0To start a Task: Task{taskName='task0'} xhJaver The current thread is xhJaver thread-1To start a Task: Task{taskName='task1'} xhJaver, thread pool series current thread name xhJaver-thread-4The current thread xhJaver is xhJaver thread-4Task handling is complete: Task{taskName='task4'} No error xhJaver the current thread is xhJaver thread-4To start a Task: Task{taskName='task5'} xhJaver, thread pool series current thread name xhJaver-thread-9The current thread xhJaver is xhJaver thread-9Task handling is complete: Task{taskName='task19'} no error here is xhJaver, thread pool series current thread name is xhJaver-thread-6The current thread is xhJaver-thread-6Task handling is complete: Task{taskName='task16'} No error xhJaver the current thread is xhJaver thread-9To start a Task: Task{taskName='task6'} xhJaver, thread pool series current thread name xhJaver-thread-7The current thread is xhJaver-thread-7Task handling is complete: Task{taskName='task17'} No error xhJaver the current thread is xhJaver thread-7To start a Task: Task{taskName='task8'} xhJaver The current thread is xhJaver thread-6To start a Task: Task{taskName='task7'} xhJaver, thread pool series current thread name xhJaver-thread-1The current thread name of the thread pool series is xhJaver-thread-8The current thread is xhJaver-thread-8Task handling is complete: Task{taskName='task18'} No error xhJaver the current thread is xhJaver thread-8To start a Task: Task{taskName='task9'} xhJaver, thread pool series current thread name xhJaver-thread-2The current thread is xhJaver-thread-2Task handling is complete: Task{taskName='task2'} No error xhJaver the current thread is xhJaver thread-2To start a Task: Task{taskName='task10'} xhJaver, thread pool series current thread name xhJaver-thread-3The current thread xhJaver is xhJaver-thread-3Task handling is complete: Task{taskName='task3'} no error here is xhJaver, thread pool series current thread name is xhJaver-thread-5The current thread xhJaver is xhJaver thread-5Task handling is complete: Task{taskName='task15'} No error xhJaver the current thread is xhJaver thread-5To start a Task: Task{taskName='task12'} xhJaver The current thread is xhJaver thread-1Task handling is complete: Task{taskName='task1'} No error xhJaver the current thread is xhJaver thread-1To start a Task: Task{taskName='task13'} xhJaver, thread pool series current thread name xhJaver-thread-0The current thread xhJaver is xhJaver thread-3To start a Task: Task{taskName='task11'} xhJaver The current thread is xhJaver thread-0Task handling is complete: Task{taskName='task0'} No error xhJaver the current thread is xhJaver thread-0To start a Task: Task{taskName='task14'} xhJaver, thread pool series current thread name xhJaver-thread-4The current thread is xhJaver-thread-4Task handling is complete: Task{taskName='task5'} no error here is xhJaver, thread pool series current thread name is xhJaver-thread-6The current thread is xhJaver-thread-6Task handling is complete: Task{taskName='task7'} no error here is xhJaver, thread pool series current thread name is xhJaver-thread-9The current thread xhJaver is xhJaver-thread-9Task handling is complete: Task{taskName='task6'} no error here is xhJaver, thread pool series current thread name is xhJaver-thread-7The current thread xhJaver is xhJaver thread-7Task handling is complete: Task{taskName='task8'} no error here is xhJaver, thread pool series current thread name is xhJaver-thread-2The current thread xhJaver is xhJaver thread-2Task handling is complete: Task{taskName='task10'} no error here is xhJaver, thread pool series current thread name is xhJaver-thread-8The current thread xhJaver is xhJaver thread-8Task handling is complete: Task{taskName='task9'} no error here is xhJaver, thread pool series current thread name is xhJaver-thread-5The current thread is xhJaver-thread-5Task handling is complete: Task{taskName='task12'} no error here is xhJaver, thread pool series current thread name is xhJaver-thread-0The current thread xhJaver is xhJaver thread-0Task handling is complete: Task{taskName='task14'} no error here is xhJaver, thread pool series current thread name is xhJaver-thread-3The current thread is xhJaver-thread-3Task handling is complete: Task{taskName='task11'} no error here is xhJaver, thread pool series current thread name is xhJaver-thread-1The current thread xhJaver is xhJaver-thread-1Task handling is complete: Task{taskName='task13'} No error xhJaver the current thread is xhJaver thread-1Closing a thread poolCopy the code
These are some of the basic uses of thread pools. The next xhJaver article will look at some thread pools in action to reinforce these ideas.
Ten, digression
XhJaver finally decided to become a blogger (the public account is also this yo), if there is any mistake in this article, please point out, I also continue to learn and grow, thank you for your correction. Jingdong probation obtainment and turned away, taking the process and everything is moving in the right direction, and I also love to which Jony – j in the “players” in the lyrics, here for you “I don’t like DaZui cannons, shout slogans, to conform the drain, want the boat I made is not afraid of the wind wave higher”, ah