24fb7b82745035f2ee3d427705a7bb83db43f742
[yangtools.git] / common / util / src / main / java / org / opendaylight / yangtools / util / concurrent / FastThreadPoolExecutor.java
1 /*
2  * Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.yangtools.util.concurrent;
10
11 import com.google.common.base.MoreObjects;
12 import com.google.common.base.MoreObjects.ToStringHelper;
13 import com.google.common.util.concurrent.ThreadFactoryBuilder;
14 import java.util.concurrent.ThreadPoolExecutor;
15 import java.util.concurrent.TimeUnit;
16
17 /**
18  * A ThreadPoolExecutor with a specified bounded queue capacity that favors creating new threads
19  * over queuing, as the former is faster.
20  *
21  * <p>See {@link SpecialExecutors#newBoundedFastThreadPool} for more details.
22  *
23  * @author Thomas Pantelis
24  */
25 public class FastThreadPoolExecutor extends ThreadPoolExecutor {
26
27     private static final long DEFAULT_IDLE_TIMEOUT_IN_SEC = 15L;
28
29     private final String threadPrefix;
30     private final int maximumQueueSize;
31
32     /**
33      * Constructs a FastThreadPoolExecutor instance.
34      *
35      * @param maximumPoolSize
36      *            the maximum number of threads to allow in the pool. Threads will terminate after
37      *            being idle for 15 seconds.
38      * @param maximumQueueSize
39      *            the capacity of the queue.
40      * @param threadPrefix
41      *            the name prefix for threads created by this executor.
42      */
43     public FastThreadPoolExecutor( final int maximumPoolSize, final int maximumQueueSize, final String threadPrefix ) {
44         this( maximumPoolSize, maximumQueueSize, DEFAULT_IDLE_TIMEOUT_IN_SEC, TimeUnit.SECONDS,
45               threadPrefix );
46     }
47
48     /**
49      * Constructs a FastThreadPoolExecutor instance.
50      *
51      * @param maximumPoolSize
52      *            the maximum number of threads to allow in the pool.
53      * @param maximumQueueSize
54      *            the capacity of the queue.
55      * @param keepAliveTime
56      *            the maximum time that idle threads will wait for new tasks before terminating.
57      * @param unit
58      *            the time unit for the keepAliveTime argument
59      * @param threadPrefix
60      *            the name prefix for threads created by this executor.
61      */
62     public FastThreadPoolExecutor( final int maximumPoolSize, final int maximumQueueSize, final long keepAliveTime,
63             final TimeUnit unit, final String threadPrefix ) {
64         // We use all core threads (the first 2 parameters below equal) so, when a task is submitted,
65         // if the thread limit hasn't been reached, a new thread will be spawned to execute
66         // the task even if there is an existing idle thread in the pool. This is faster than
67         // handing the task to an existing idle thread via the queue. Once the thread limit is
68         // reached, subsequent tasks will be queued. If the queue is full, tasks will be rejected.
69
70         super( maximumPoolSize, maximumPoolSize, keepAliveTime, unit,
71                 new TrackingLinkedBlockingQueue<>(maximumQueueSize) );
72
73         this.threadPrefix = threadPrefix;
74         this.maximumQueueSize = maximumQueueSize;
75
76         setThreadFactory( new ThreadFactoryBuilder().setDaemon( true )
77                                                  .setNameFormat( threadPrefix + "-%d" ).build() );
78
79         if (keepAliveTime > 0) {
80             // Need to specifically configure core threads to timeout.
81             allowCoreThreadTimeOut( true );
82         }
83
84         setRejectedExecutionHandler( CountingRejectedExecutionHandler.newAbortPolicy() );
85     }
86
87     public long getLargestQueueSize() {
88         return ((TrackingLinkedBlockingQueue<?>)getQueue()).getLargestQueueSize();
89     }
90
91     protected ToStringHelper addToStringAttributes( final ToStringHelper toStringHelper ) {
92         return toStringHelper;
93     }
94
95     @Override
96     public final String toString() {
97         return addToStringAttributes( MoreObjects.toStringHelper( this )
98                 .add( "Thread Prefix", threadPrefix )
99                 .add( "Current Thread Pool Size", getPoolSize() )
100                 .add( "Largest Thread Pool Size", getLargestPoolSize() )
101                 .add( "Max Thread Pool Size", getMaximumPoolSize() )
102                 .add( "Current Queue Size", getQueue().size() )
103                 .add( "Largest Queue Size", getLargestQueueSize() )
104                 .add( "Max Queue Size", maximumQueueSize )
105                 .add( "Active Thread Count", getActiveCount() )
106                 .add( "Completed Task Count", getCompletedTaskCount() )
107                 .add( "Total Task Count", getTaskCount() ) ).toString();
108     }
109 }