c44864350e863dc639e307d23fc343efbc38bfc1
[yangtools.git] / common / util / src / main / java / org / opendaylight / yangtools / util / concurrent / CountingRejectedExecutionHandler.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.Preconditions;
12
13 import java.util.concurrent.RejectedExecutionHandler;
14 import java.util.concurrent.ThreadPoolExecutor;
15 import java.util.concurrent.atomic.AtomicLongFieldUpdater;
16
17 import org.opendaylight.yangtools.util.ExecutorServiceUtil;
18
19 /**
20  * A RejectedExecutionHandler that delegates to a backing RejectedExecutionHandler and counts the
21  * number of rejected tasks.
22  *
23  * @author Thomas Pantelis
24  */
25 public class CountingRejectedExecutionHandler implements RejectedExecutionHandler {
26     private static final AtomicLongFieldUpdater<CountingRejectedExecutionHandler> COUNTER_UPDATER =
27             AtomicLongFieldUpdater.newUpdater(CountingRejectedExecutionHandler.class, "rejectedTaskCounter");
28     private final RejectedExecutionHandler delegate;
29     private volatile long rejectedTaskCounter;
30
31     /**
32      * Constructor.
33      *
34      * @param delegate the backing RejectedExecutionHandler.
35      */
36     public CountingRejectedExecutionHandler( final RejectedExecutionHandler delegate ) {
37         this.delegate = Preconditions.checkNotNull( delegate );
38     }
39
40     @Override
41     public void rejectedExecution( final Runnable task, final ThreadPoolExecutor executor ) {
42         COUNTER_UPDATER.incrementAndGet(this);
43         delegate.rejectedExecution( task, executor );
44     }
45
46     /**
47      * Returns the rejected task count.
48      */
49     public long getRejectedTaskCount() {
50         return rejectedTaskCounter;
51     }
52
53     /**
54      * Returns s counting handler for rejected tasks that runs the rejected task directly in the
55      * calling thread of the execute method, unless the executor has been shut down, in which case
56      * the task is discarded.
57      */
58     public static CountingRejectedExecutionHandler newCallerRunsPolicy() {
59         return new CountingRejectedExecutionHandler( new ThreadPoolExecutor.CallerRunsPolicy() );
60     }
61
62     /**
63      * Returns a counting handler for rejected tasks that throws a RejectedExecutionException.
64      */
65     public static CountingRejectedExecutionHandler newAbortPolicy() {
66         return new CountingRejectedExecutionHandler( new ThreadPoolExecutor.AbortPolicy() );
67     }
68
69     /**
70      * Returns a counting handler for rejected tasks that that blocks on the
71      * {@link ThreadPoolExecutor}'s backing queue until it can add the task to the queue.
72      */
73     public static CountingRejectedExecutionHandler newCallerWaitsPolicy() {
74         return new CountingRejectedExecutionHandler( ExecutorServiceUtil.waitInQueueExecutionHandler() );
75     }
76 }