“This is the 8th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021”

Java thread pool size and thread pool deadlock

Optimize thread pool size

The size of the thread pool has a certain impact on system performance. If it is too large or too small, the system performance cannot be optimized. The size of the thread pool does not need to be precise, as long as it is not too large or too small. A formula for estimating the size of a thread pool is given in the book:

Thread pool size = Number of cpus * target CPU usage *(1 + ratio of wait time to computation time)

Thread pool deadlocks

If task A in the thread pool submits task B to the thread pool during execution, task B is added to the wait queue of the thread pool. If task A ends, the execution result of task B needs to be waited. It is possible that all worker threads in the thread pool are waiting for the result of a task that is waiting to be executed in a blocking queue. There are no threads in the thread pool that can process the task in the blocking queue, and the wait will continue forever, resulting in a deadlock.

It is a good idea to submit tasks to a thread pool that are independent of each other rather than dependent on each other. Consider submitting tasks that depend on each other to separate thread pools for execution.

Java thread pool exception handling

When submitting a task using ThreadPoolExecutor, some tasks throw an exception, but the thread pool does not inform the task, that is, the thread pool eats the exception in the task, you can change the submit submission to execute, or you can change the ThreadPoolExecutor line Program pool for expansion. Wrap the submitted task:

package com.wkcto.threadpool; import java.util.concurrent.*; Public class Test08 {// Private static class TraceThreadPollExecutor extends ThreadPoolExecutor{ public TraceThreadPollExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); } public Runnable wrap(Runnable task, Runnable task, Runnable task, Runnable task, Exception exception){ return new Runnable() { @Override public void run() { try { task.run(); }catch (Exception e ){ exception.printStackTrace(); throw e; }}}; } // Override public Future submit(Runnable task) {return super.submit(wrap(task, new Exception()));  } @override public void execute(Runnable command) {super.execute(wrap(command, new Exception())); Private static class DivideTask implements Runnable{private int x; private static class DivideTask implements Runnable; private int y; public DivideTask(int x, int y) { this.x = x; this.y = y; } @override public void run() {system.out.println (thread.currentThread ().getName() + "+ x +"/" + y + "=" + (x/y)); }} public static void main(String[] args) {ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(0, 0) Integer.MAX_VALUE, 0, TimeUnit.SECONDS, new SynchronousQueue<>()); ThreadPoolExecutor poolExecutor = new TraceThreadPollExecutor(0, integer.max_value, 0, timeUnit.seconds, new SynchronousQueue<>()); // Add a task to the thread pool for (int I = 0; i < 5; i++) { poolExecutor.submit(new DivideTask(10, i)); // poolExecutor.execute(new DivideTask(10, i)); }}}Copy the code