ThreadPoolExecutor eight kinds of refuse analysis methods

Transfer: http://www.kailing.pub/article/index/arcid/255.html

Foreword

Speaking java thread pool most familiar than ExecutorService interfaces, this api under jdk1.5 new java.util.concurrent package, which greatly simplifies the development of multi-threaded code. And whether you use FixedThreadPool behind its implementation is still CachedThreadPool ThreadPoolExecutor. ThreadPoolExecutor buffer pool is a typical design of the product, because the size of the pool when the pool is not enough volume of the carrier, involving the rejection policy. JDK has four preset thread pool denial strategy, in conjunction with the following detailed scenes talk of these strategies use scene, and we reject policies which could expand.

Pool design ideas

Pool design, then it should not be a new term. As our common thread pool java, jdbc connection pool, redis connection pools is to represent this type of design implementation. This design will initially default resources to solve the problem is to offset the consumption of each access to resources, such as thread creation overhead, overhead obtain remote connection and so on. Like you go to the cafeteria Dafan Dafan aunt would put several Iimori good place where you came directly to holding a lunch box food to eat, you do not have a temporary hold rice and food fight, efficiency is high. In addition to the initialization resource, further comprising the pool design of these features: initial value, the active value of the pond, the pond maximum pond, etc. These features can be mapped directly to the member attributes java thread pools and database connection pool.

Thread Pool trigger timing refused strategy

And the data source connection pool is not the same, except that the initial size of the thread pool and pond maximum, more than one queue blocking buffer. Exceeds the maximum number of connection pool when the data source connection is connected to a general pool deny policy request is triggered, the waiting time is a blocking strategy is generally provided either directly thrown exception. The trigger timing of the thread pool below:

As shown, you want to understand the specific meaning of the thread pool when the trigger denial rough, need to be clearly above three parameters, three parameters are the result of overall coordination, rather than simply exceeds the maximum number of threads in the thread will trigger denial rough, when after submitting the number of tasks is greater than corePoolSize, it will put priority queue buffer, only to fill the buffer, will determine whether the currently running task is greater than maxPoolSize, will create a new thread processing is less than. Greater than it causes a denial strategy, conclusion is: The current strategy will refuse to submit to trigger the thread pool is greater than the number of tasks (maxPoolSize + queueCapacity) a.

JDK four built-in thread pool denial policy

Rejection policy interface definition

Before analyzing the thread pool that comes with JDK deny policy, refused to look at JDK defined strategy interfaces, as follows:

 

public interface RejectedExecutionHandler { void rejectedExecution(Runnable r, ThreadPoolExecutor executor); }

 

Interface definition is very clear, when the trigger rejection policy, thread pool calls you set specific strategies, currently committed to the task and thread pool instance itself passed to deal with you, for what specific treatment, different scenarios will have different considerations, Let's look at what JDK built for us to achieve:

CallerRunsPolicy (caller operating strategy)

 

    public static class CallerRunsPolicy implements RejectedExecutionHandler { public CallerRunsPolicy() { } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { r.run(); } } }

 

Function: When the trigger rejection policy, as long as the thread pool is not closed, it is processed by the current thread submit tasks.

Usage scenarios: general does not allow the failure of performance requirements, the use of a small amount of concurrency at the scene, because the thread pool does not close under normal circumstances, the task is submitted will be run, but because it is the caller own thread execution, when multiple submissions task will block the follow-up task execution, performance and efficiency of naturally slow.

AbortPolicy (suspension policy)

 

    public static class AbortPolicy implements RejectedExecutionHandler { public AbortPolicy() { } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString()); } }

 

Function: When the trigger rejection policy, refused to carry out a direct throw an exception, suspension policy is meant to interrupt the current flow of execution

Usage scenarios: this is no particular scene, but the right thing to throw exception handling. ThreadPoolExecutor default strategy is AbortPolicy, ExecutorService series ThreadPoolExecutor interface settings are not shown because deny policy, so the default is this. Note, however, ExecutorService the thread pool instance queue is unbounded, that is to say the memory Chengbao will not trigger rejection policy. When your own custom thread pool instance, the use of this strategy must handle an exception thrown when a policy is triggered, because he will interrupt the current flow of execution.

DiscardPolicy (discard policy)

 

    public static class DiscardPolicy implements RejectedExecutionHandler { public DiscardPolicy() { } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { } }

 

Function: Direct quiet discard this task, does not trigger any action

Usage scenarios: If the task you submit does not matter, you can use it. Because it is empty achieved, it will quietly swallow your task. So this is basically not a strategy

DiscardOldestPolicy (abandon old strategies)

 

    public static class DiscardOldestPolicy implements RejectedExecutionHandler { public DiscardOldestPolicy() { } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { e.getQueue().poll(); e.execute(r); } } }

 

Function: If the thread pool is not closed, the head of the queue will pop elements, and then try to perform

Use scene: this strategy will still discard task, but also no sound when discarded, but is characterized by discarded the old task is not performed, and the tasks to be performed is a higher priority. Message based on this feature, I can think of that scene, send messages, and modify messages after the news release went out, had not been implemented, then update the news again, this time version of the message is not submitted by the Executive than it is now lower version can be discarded. Because the queue there may exist a lower version of the message the message will be queued for execution, so when you actually process the message must be good news Version Comparison

Reject third-party implementation of the strategy

dubbo threads in denial policy

 

public class AbortPolicyWithReport extends ThreadPoolExecutor.AbortPolicy { protected static final Logger logger = LoggerFactory.getLogger(AbortPolicyWithReport.class); private final String threadName; private final URL url; private static volatile long lastPrintTime = 0; private static Semaphore guard = new Semaphore(1); public AbortPolicyWithReport(String threadName, URL url) { this.threadName = threadName; this.url = url; } @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { String msg = String.format("Thread pool is EXHAUSTED!" + " Thread Name: %s, Pool Size: %d (active: %d, core: %d, max: %d, largest: %d), Task: %d (completed: %d)," + " Executor status:(isShutdown:%s, isTerminated:%s, isTerminating:%s), in %s://%s:%d!", threadName, e.getPoolSize(), e.getActiveCount(), e.getCorePoolSize(), e.getMaximumPoolSize(), e.getLargestPoolSize(), e.getTaskCount(), e.getCompletedTaskCount(), e.isShutdown(), e.isTerminated(), e.isTerminating(), url.getProtocol(), url.getIp(), url.getPort()); logger.warn(msg); dumpJStack(); throw new RejectedExecutionException(msg); } private void dumpJStack() { //省略实现 } }

 

It can be seen when dubbo worker threads refusal triggered a thread, mainly to do three things, the principle is to try to give users a clear trigger real policy reasons for refusal thread

  • Output a warning level log, the log content is detailed parameters of the thread pool, and the current state of the thread pool, there are some details of the task currently denied. We can say that this log, use dubbo have had experience in the operation and maintenance of production is more or less seen, this log is simply a model log printing, as well as a model for other spring log printing. Thanks to such a detailed log, you can easily locate the problem
  • Output current thread stack details of this very useful when you can not locate the problem by the above log information, the scene of dump thread context information that you find straw problem, this can refer to "dubbo thread pool is exhausted events - "CyclicBarrier to blame." "
  • Continue to refuse to execute an exception is thrown, the failure of this mission, the inherited characteristics of the JDK default deny policy

Netty threads in the pool rejection policy

 

    private static final class NewThreadRunsPolicy implements RejectedExecutionHandler { NewThreadRunsPolicy() { super(); } public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { try { final Thread t = new Thread(r, "Temporary task executor"); t.start(); } catch (Throwable e) { throw new RejectedExecutionException( "Failed to start a new thread", e); } } }

 

Netty is achieved much like the JDK CallerRunsPolicy, reluctant to discard task. The difference is, CallerRunsPolicy task is performed directly in the caller's thread. The Netty is a new thread to handle. So, Netty is achieved compared to the caller using face execution strategy can be extended to support the efficient performance of the scene. But also note that, to achieve Netty's, without making any judgment constraints when a thread is created, that is to say as long as the system resources will also create a new thread to handle, until no new new thread, and will throw failed to create thread exception

activeMq threads in the pool rejection policy

 

 new RejectedExecutionHandler() { @Override public void rejectedExecution(final Runnable r, final ThreadPoolExecutor executor) { try { executor.getQueue().offer(r, 60, TimeUnit.SECONDS); } catch (InterruptedException e) { throw new RejectedExecutionException("Interrupted waiting for BrokerService.worker"); } throw new RejectedExecutionException("Timed Out while attempting to enqueue Task."); } });

 

activeMq in strategy belong utmost to implement the task type, when the trigger rejection policy, try again a minute task into the task queue, when the one minute time-out did not succeed, it throws an exception

pinpoint the thread pool denial policy

 

public class RejectedExecutionHandlerChain implements RejectedExecutionHandler { private final RejectedExecutionHandler[] handlerChain; public static RejectedExecutionHandler build(List<RejectedExecutionHandler> chain) { Objects.requireNonNull(chain, "handlerChain must not be null"); RejectedExecutionHandler[] handlerChain = chain.toArray(new RejectedExecutionHandler[0]); return new RejectedExecutionHandlerChain(handlerChain); } private RejectedExecutionHandlerChain(RejectedExecutionHandler[] handlerChain) { this.handlerChain = Objects.requireNonNull(handlerChain, "handlerChain must not be null"); } @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { for (RejectedExecutionHandler rejectedExecutionHandler : handlerChain) { rejectedExecutionHandler.rejectedExecution(r, executor); } } }

 

He refused to pinpoint the strategies to achieve very characteristic, and other implementations are different. He refused to define a strategy chain, wraps a denial policy list, when the trigger rejection policy, the policy will be followed by the implementation chain rejectedExecution again

Epilogue

Previously rejected the timing of the trigger strategy from the thread pool design ideas, as well as java thread pool thread pool leads to denial-defined strategy interfaces. Supplemented JDK four built, and four refused to define policies third party open source software describes the thread pool scene refused to use a variety of ideas and strategies to achieve. After reading this article make you want to deny java thread pool strategy to develop a deeper understanding of the application can be more flexible according to different usage scenarios.

Guess you like

Origin www.cnblogs.com/wjqhuaxia/p/11762150.html