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