Executor: Wait for specific tasks to finish - java

The server application I am running gets multiple requests for tasks which I want to handle using a task system.
Each task is represented as a Runnable that will demand n number of threads from a thread pool where n is smaller or equal to the thread pool size. The thread pool of course is necessary in order to not overload the CPU with too many threads.
However, some of those tasks can be multi threaded and some can not. That is why it might be necessary for one task to wait for all its specific threads to finish in order to merge the results from those threads for the final result.
If one uses multiple Thread instances one might join those like this:
try {
// Wait for all threads to finish their tasks
for (Thread thread : threads) {
thread.join();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
// Finish job here ..
but I'd need something like this using java.util.concurrent.Executor or anything similar that works with a thread pool.

You can use ExecutorService along with a CyclicBarrier for each task as follows:
public class ThreadedTask implements Runnable {
CyclicBarrier barrier;
public ThreadedTask(CyclicBarrier barrier) {
this.barrier = barrier;
}
#Override
public void run() {
// do something
barrier.await();
}
}
ExecutorService executor = Executors.newFixedThreadPool(pool_size);
...
CyclicBarrier barrier = new CyclicBarrier(n+1);
for(int i=0; i<n; i++) {
// launch all tasks
executor.submit(new ThreadedTask(barrier));
}
// waits for the tasks to finish or timeout
barrier.await(seconds, TimeUnit.SECONDS);

If I understand you correctly, you will need something like this (but your architecture seems too complicated):
class MyTask implements Runnable {
#Override
public void run() {
// some work
}
}
After that:
ExecutorService executorService = Executors.newFixedThreadPool(2000);
ArrayList<Future> futures = new ArrayList<>();
futures.add(executorService.submit(new MyTask()));
futures.add(executorService.submit(new MyTask()));
futures.add(executorService.submit(new MyTask()));
for (Future future: futures) {
try {
future.get(100, TimeUnit.SECONDS);
} catch (Throwable cause) {
// process cause
}
}
Each future.get() will wait for task ending (max 100 seconds in this example).

Related

awaitQuiescence does not return after timeout

I'm trying to use the awaitQuiescence method from ForkJoinPool to wait until all submitted tasks are finished, or return false if the tasks are not yet completed after the timeout.
Practically all of submitted tasks can add additional tasks to the pool, so I can't use the awaitTermination method, because that would block those additional tasks from being submitted.
However, the awaitQuiescence does not return anything, even when the specified time is over.
I tried to crystallize the issue in the code below. The CountDownLatch.await will never be triggered, but why does the awaitQuiescence method not return false?
public static void main(String[] args) {
final ForkJoinPool test = new ForkJoinPool(1,
ForkJoinPool.defaultForkJoinWorkerThreadFactory, null,true);
final CountDownLatch latch = new CountDownLatch(1);
test.execute(() -> {
try {
System.out.println("Sleeping");
Future<Double> f = test.submit(() -> {
latch.await();
return 0d;
});
System.out.println(f.get());
System.out.println("Waking up");
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
});
System.out.println(test.awaitQuiescence(1, TimeUnit.SECONDS));
}
Thanks very much!
why does the awaitQuiescence method not return false?
It seems that awaitQuiescence ignores timeout while there are pending tasks and executes the tasks in the caller's thread (see source code).
Thread dump:
"ForkJoinPool-1-worker-1" [...] Object.wait() [...]
java.lang.Thread.State: WAITING (on object monitor)
[...]
at java.util.concurrent.ForkJoinTask.get(ForkJoinTask.java:995)
[...]
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
[...]
"main" [...] waiting on condition [...]
java.lang.Thread.State: WAITING (parking)
[...]
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)
[...]
at java.util.concurrent.ForkJoinTask$AdaptedCallable.exec(ForkJoinTask.java:1445)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool.awaitQuiescence(ForkJoinPool.java:3097)
[...]
"main" thread executes second task and waits for the latch, hence awaitQuiescence never terminates.
In my opinion this is a bug. Based on the javadoc I'd assume that the max running time of the method ("the maximum time to wait") is approximately timeout, but upper bound is actually more like the time of execution of all pending tasks and all of their "descendants" (possibly except the terminal ones).
On the other hand FJ pool is not quite intended for this type of tasks (with non-pool-managed synchronization). From the ForkJoinTask's javadoc:
Computations should ideally avoid synchronized methods or blocks, and
should minimize other blocking synchronization apart from joining
other tasks or using synchronizers such as Phasers that are advertised
to cooperate with fork/join scheduling.
[...]
It is possible to define and use ForkJoinTasks that may block, but
doing do requires three further considerations: (1) Completion of few
if any other tasks should be dependent on a task that blocks on
external synchronization or I/O. Event-style async tasks that are
never joined (for example, those subclassing CountedCompleter) often
fall into this category. (2) To minimize resource impact, tasks should
be small; ideally performing only the (possibly) blocking action. (3)
Unless the ForkJoinPool.ManagedBlocker API is used, or the number of
possibly blocked tasks is known to be less than the pool's
ForkJoinPool.getParallelism() level, the pool cannot guarantee that
enough threads will be available to ensure progress or good
performance.
Consider using ThreadPoolExecutor and/or emulating awaitQuiescence (e.g. using Phaser). Sketch of the possible implementation:
class TaskTrackingExecutorService implements ExecutorService {
private final ExecutorService delegate;
private final Phaser taskTracker = new Phaser();
public TaskTrackingExecutorService(ExecutorService delegate) {
this.delegate = delegate;
}
#Override
public <T> Future<T> submit(Callable<T> task) {
return delegate.submit(() -> {
taskTracker.register();
try {
return task.call();
} finally {
taskTracker.arriveAndDeregister();
}
});
}
#Override
public void execute(Runnable command) {
submit(Executors.callable(command));
}
public boolean awaitQuiescence(long timeout, TimeUnit timeUnit) throws InterruptedException {
taskTracker.register();
try {
taskTracker.awaitAdvanceInterruptibly(taskTracker.arriveAndDeregister(), timeout, timeUnit);
return true;
} catch (TimeoutException e) {
return false;
}
}
#Override
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
return delegate.awaitTermination(timeout, unit);
}
// rest is similar: either use submit method or the delegate.
}
public class Test {
public static void main(String[] args) throws InterruptedException {
TaskTrackingExecutorService pool =
new TaskTrackingExecutorService(Executors.newCachedThreadPool());
CountDownLatch latch = new CountDownLatch(1);
pool.execute(() -> {
System.out.println("Sleeping");
Future<Double> f = pool.submit(() -> {
latch.await();
return 0d;
});
try {
System.out.println(f.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
System.out.println("Waking up");
}
);
System.out.println(pool.awaitQuiescence(2, TimeUnit.SECONDS));
}
}

Handling 10000 threads using Executor

I have a web service which is continuously accessed by more than 20 servers which are sending data. I have used activeMQ where data is queued for some time and than using async task this data is dequed.
My async task thread class is shown below.
public class myConsumer {
public void asyncConsumer() throws InterruptedException, ExecutionException{
final MyReceiver receiver = new MyReceiver();
final ExecutorService executorService = Executors.newSingleThreadExecutor();
try{
Future future = executorService.submit(new Runnable() {
public void run() {
receiver.receiveMessage();
}
});
executorService.shutdown();
executorService.awaitTermination(5, TimeUnit.SECONDS);
}catch (InterruptedException e) {
logger.error("tasks interrupted");
}finally {
if (!executorService.isTerminated()) {
logger.error("cancel non-finished tasks");
}
executorService.shutdownNow();
}
}
}
I have 10000 of threads running. My applcation server is stopped due to unusual behavior. How to handle this many no of thread using above code.
You should use a thread pool executor rather than single thread executor, and make sure it's only one instance of the thread pool receiving messages. This way you can keep track of and limit the amount of concurrent threads.
Here's an example of how it can be done. By having the executorservice static you assure that it's only one instance, and it's limited to max 10 simultaneous threads. When you call asyncConsumer to process a received message a MyReceiver (which I assume is going to process the message) is created and invoked inside the thread pool.
public class MyConsumer {
static final ExecutorService executorService = Executors.newFixedThreadPool(10);
public void asyncConsumer() {
Future future = executorService.submit(new Runnable() {
public void run() {
new MyReceiver().receiveMessage();
}
});
}
}

Some complex Threading concept [duplicate]

This question already has answers here:
Run Java Threads sequentially
(13 answers)
Closed 9 years ago.
how to Execute threads sequentially ? (e.g i have 3 threads T1,T2,T3 and i want to start these threads same time but ensure that they should run sequentially one after other like first T1 then T2 and at last T3.)
Thread t1= new Thread(new Runnable()
{
void run()
{System.out.println("inside Thread1");}
});
Thread t2= new Thread(new Runnable()
{
void run()
{System.out.println("inside Thread2");}
});
Thread t3= new Thread(new Runnable()
{
void run()
{System.out.println("inside Thread3");}
});
t1.start();
t2.strat();
t3.start();
output:
inside Thread1
inside Thread2
inside Thread3
each time u run o/p should be as shown above.
In my humble opinion, you perhaps do not need threads, just call T1(), T2(), T3() methods sequentially in your code?
Threads are used to run multiple tasks in parallel.
You can synchronize these threads through flag/s. You can also use inbuilt synchronizers provided by Java like BlockingQueue.
Use BlockingQueues to synchronize the threads
final BlockingQueue q1 = new SynchronousQueue();
final BlockingQueue q2 = new SynchronousQueue();
Thread t1 = new Thread() {
public void run() {
...
try {
q1.put(new Object());
} catch (InterruptedException e) {
}
};
};
Thread t2 = new Thread() {
public void run() {
try {
q1.take();
...
q2.put(new Object());
} catch (InterruptedException e) {
}
}
};
Thread t3 = new Thread() {
public void run() {
try {
q2.take();
...
} catch (InterruptedException e) {
}
}
};
t1.start();
t2.start();
t3.start();
Threads are used to run multiple tasks at a same time.
In your case you need different methods called sequentially rather than Threads.
You should use:
class Methods_Than_Threads{
void T1()
{
//something
}
void T2()
{
//something
}
void T3()
{
//something
}
public static void main(String []args)
{
T1();//First T1
T2();//Second T2
T3();//Third T3
}
}
You should separate the actual tasks from how they are executed. I.e. don't extend Thread and overwrite run, instead implement Runnable as the task and don't care about the way it is executed.
That way you can design (+change later) the way you execute tasks independently from the actual implementation of a task.
E.g. Call each .run() directly if you want to execute them after each other or let some Executor handle them or even run them via new Thread manually.
If they have to wait on each other you could also use a Future. For example:
class ProcessingChainElement implements Callable<String> {
private final Future<String> previous;
public ProcessingChainElement(Future<String> previousResult) {
previous = previousResult;
}
#Override
public String call() throws Exception {
// prepare something that may take some time but does not depend on
// any previous result
Thread.sleep(500);
// get result from previous task, this blocks until it is available
result = previous.get() + " [" + System.currentTimeMillis() + "]";
return result;
}
}
And build a chain of tasks that can be executed in any way you want.
ExecutorService executor = Executors.newFixedThreadPool(3);
Future<String> result1 = executor.submit(...
Future<String> result2 = executor.submit(new ProcessingChainElement(result1));
...
Result is that each task can wait on results of a previous task but may very well run in parallel if there is anything that can be run in parallel.
Example http://ideone.com/VAg8q3 demonstrates that 3 tasks that take >= 500ms each and depend on each other could be done much quicker than actually running them in sequence.

Why does ExecutorService keep executing when threads are blocking?

I am trying to write a part of a multithreaded program where each thread from a fixed thread pool tries to fetch an object from a Queue and if the Queue is empty the thread waits.
The problem I am experiencing is that the memory used by the program keeps increasing.
public class Ex3 {
public static LinkedBlockingQueue<Integer> myLBQ = new LinkedBlockingQueue<Integer>(10);
public static void main(String argc[]) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(3);
myLBQ.add(new Integer(1));
for (;;) {
executor.execute(new MyHandler(myLBQ));
}
}
}
class MyHandler implements Runnable {
LinkedBlockingQueue<Integer> myLBQ;
MyHandler(LinkedBlockingQueue<Integer> myLBQ) {
this.myLBQ = myLBQ;
}
public void run() {
try {
myLBQ.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I don't understand why the executor.execute keeps firing when the threads should be waiting for an item to be added to the Queue. How do I modify my code to reflect this?
This adds tasks to the executor as fast as it can.
for (;;) {
executor.execute(new MyHandler(myLBQ));
}
This will consume about 200 MB per second. It doesn't have anything to do with whether there are tasks to perform or not.
If you don't want to do this I suggest you move the loop to the runnable and add only one. This will cause it to wait for tasks forever.
A better approach is to use the ExecutorService's builtin queue to queue tasks.
ExecutorService executor = Executors.newFixedThreadPool(3);
final int taskId = 1;
executor.submit(new Runnable() {
#Override
public void run() {
doSomething(taskId);
}
});
executor.shutdown();
This does the same thing, but is much simpler IMHO.
it's because you're creating a gazillion instances of MyHandler and inserting them in the internal queue of the executor.
That infinite for loop is quite mean.

ThreadPoolExecutor Block When its Queue Is Full?

I am trying to execute lots of tasks using a ThreadPoolExecutor. Below is a hypothetical example:
def workQueue = new ArrayBlockingQueue<Runnable>(3, false)
def threadPoolExecutor = new ThreadPoolExecutor(3, 3, 1L, TimeUnit.HOURS, workQueue)
for(int i = 0; i < 100000; i++)
threadPoolExecutor.execute(runnable)
The problem is that I quickly get a java.util.concurrent.RejectedExecutionException since the number of tasks exceeds the size of the work queue. However, the desired behavior I am looking for is to have the main thread block until there is room in the queue. What is the best way to accomplish this?
In some very narrow circumstances, you can implement a java.util.concurrent.RejectedExecutionHandler that does what you need.
RejectedExecutionHandler block = new RejectedExecutionHandler() {
rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
executor.getQueue().put( r );
}
};
ThreadPoolExecutor pool = new ...
pool.setRejectedExecutionHandler(block);
Now. This is a very bad idea for the following reasons
It's prone to deadlock because all the threads in the pool may die before the thing you put in the queue is visible. Mitigate this by setting a reasonable keep alive time.
The task is not wrapped the way your Executor may expect. Lots of executor implementations wrap their tasks in some sort of tracking object before execution. Look at the source of yours.
Adding via getQueue() is strongly discouraged by the API, and may be prohibited at some point.
A almost-always-better strategy is to install ThreadPoolExecutor.CallerRunsPolicy which will throttle your app by running the task on the thread which is calling execute().
However, sometimes a blocking strategy, with all its inherent risks, is really what you want. I'd say under these conditions
You only have one thread calling execute()
You have to (or want to) have a very small queue length
You absolutely need to limit the number of threads running this work (usually for external reasons), and a caller-runs strategy would break that.
Your tasks are of unpredictable size, so caller-runs could introduce starvation if the pool was momentarily busy with 4 short tasks and your one thread calling execute got stuck with a big one.
So, as I say. It's rarely needed and can be dangerous, but there you go.
Good Luck.
What you need to do is to wrap your ThreadPoolExecutor into Executor which explicitly limits amount of concurrently executed operations inside it:
private static class BlockingExecutor implements Executor {
final Semaphore semaphore;
final Executor delegate;
private BlockingExecutor(final int concurrentTasksLimit, final Executor delegate) {
semaphore = new Semaphore(concurrentTasksLimit);
this.delegate = delegate;
}
#Override
public void execute(final Runnable command) {
try {
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
final Runnable wrapped = () -> {
try {
command.run();
} finally {
semaphore.release();
}
};
delegate.execute(wrapped);
}
}
You can adjust concurrentTasksLimit to the threadPoolSize + queueSize of your delegate executor and it will pretty much solve your problem
You could use a semaphore to block threads from going into the pool.
ExecutorService service = new ThreadPoolExecutor(
3,
3,
1,
TimeUnit.HOURS,
new ArrayBlockingQueue<>(6, false)
);
Semaphore lock = new Semaphore(6); // equal to queue capacity
for (int i = 0; i < 100000; i++ ) {
try {
lock.acquire();
service.submit(() -> {
try {
task.run();
} finally {
lock.release();
}
});
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
Some gotchas:
Only use this pattern with a fixed thread pool. The queue is unlikely to be full often, thus new threads won't be created. Check out the java docs on ThreadPoolExecutor for more details: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html There is a way around this, but it is out of scope of this answer.
Queue size should be higher than the number of core threads. If we were to make the queue size 3, what would end up happening is:
T0: all three threads are doing work, the queue is empty, no permits are available.
T1: Thread 1 finishes, releases a permit.
T2: Thread 1 polls the queue for new work, finds none, and waits.
T3: Main thread submits work into the pool, thread 1 starts work.
The example above translates to thread the main thread blocking thread 1. It may seem like a small period, but now multiply the frequency by days and months. All of a sudden, short periods of time add up to a large amount of time wasted.
This is what I ended up doing:
int NUM_THREADS = 6;
Semaphore lock = new Semaphore(NUM_THREADS);
ExecutorService pool = Executors.newCachedThreadPool();
for (int i = 0; i < 100000; i++) {
try {
lock.acquire();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
pool.execute(() -> {
try {
// Task logic
} finally {
lock.release();
}
});
}
A fairly straightforward option is to wrap your BlockingQueue with an implementation that calls put(..) when offer(..) is being invoked:
public class BlockOnOfferAdapter<T> implements BlockingQueue<T> {
(..)
public boolean offer(E o) {
try {
delegate.put(o);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
return true;
}
(.. implement all other methods simply by delegating ..)
}
This works because by default put(..) waits until there is capacity in the queue when it is full, see:
/**
* Inserts the specified element into this queue, waiting if necessary
* for space to become available.
*
* #param e the element to add
* #throws InterruptedException if interrupted while waiting
* #throws ClassCastException if the class of the specified element
* prevents it from being added to this queue
* #throws NullPointerException if the specified element is null
* #throws IllegalArgumentException if some property of the specified
* element prevents it from being added to this queue
*/
void put(E e) throws InterruptedException;
No catching of RejectedExecutionException or complicated locking necessary.
Here is my code snippet in this case:
public void executeBlocking( Runnable command ) {
if ( threadPool == null ) {
logger.error( "Thread pool '{}' not initialized.", threadPoolName );
return;
}
ThreadPool threadPoolMonitor = this;
boolean accepted = false;
do {
try {
threadPool.execute( new Runnable() {
#Override
public void run() {
try {
command.run();
}
// to make sure that the monitor is freed on exit
finally {
// Notify all the threads waiting for the resource, if any.
synchronized ( threadPoolMonitor ) {
threadPoolMonitor.notifyAll();
}
}
}
} );
accepted = true;
}
catch ( RejectedExecutionException e ) {
// Thread pool is full
try {
// Block until one of the threads finishes its job and exits.
synchronized ( threadPoolMonitor ) {
threadPoolMonitor.wait();
}
}
catch ( InterruptedException ignored ) {
// return immediately
break;
}
}
} while ( !accepted );
}
threadPool is a local instance of java.util.concurrent.ExecutorService which has been initialized already.
I solved this problem using a custom RejectedExecutionHandler, which simply blocks the calling thread for a little while and then tries to submit the task again:
public class BlockWhenQueueFull implements RejectedExecutionHandler {
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
// The pool is full. Wait, then try again.
try {
long waitMs = 250;
Thread.sleep(waitMs);
} catch (InterruptedException interruptedException) {}
executor.execute(r);
}
}
This class can just be used in the thread-pool executor as a RejectedExecutionHandler like any other. In this example:
executorPool = new def threadPoolExecutor = new ThreadPoolExecutor(3, 3, 1L, TimeUnit.HOURS, workQueue, new BlockWhenQueueFull())
The only downside I see is that the calling thread might get locked slightly longer than strictly necessary (up to 250ms). For many short-running tasks, perhaps decrease the wait-time to 10ms or so. Moreover, since this executor is effectively being called recursively, very long waits for a thread to become available (hours) might result in a stack overflow.
Nevertheless, I personally like this method. It's compact, easy to understand, and works well. Am I missing anything important?
Ok, old thread but this is what I found when searching for blocking thread executor. My code tries to get a semaphore when the task is submitted to the task queue. This blocks if there are no semaphores left. As soon as a task is done the semaphore is released with the decorator. Scary part is that there is a possibility of losing semaphore but that could be solved with for example a timed job that just clears semaphores on a timed basis.
So here my solution:
class BlockingThreadPoolTaskExecutor(concurrency: Int) : ThreadPoolTaskExecutor() {
companion object {
lateinit var semaphore: Semaphore
}
init {
semaphore = Semaphore(concurrency)
val semaphoreTaskDecorator = SemaphoreTaskDecorator()
this.setTaskDecorator(semaphoreTaskDecorator)
}
override fun <T> submit(task: Callable<T>): Future<T> {
log.debug("submit")
semaphore.acquire()
return super.submit(task)
}
}
private class SemaphoreTaskDecorator : TaskDecorator {
override fun decorate(runnable: Runnable): Runnable {
log.debug("decorate")
return Runnable {
try {
runnable.run()
} finally {
log.debug("decorate done")
semaphore.release()
}
}
}
}
One could overwrite ThreadPoolExecutor.execute(command) to use a Semaphore, e.g.:
/**
* The setup answering the question needs to have:
*
* permits = 3
* corePoolSize = permits (i.e. 3)
* maximumPoolSize = corePoolSize (i.e. 3)
* workQueue = anything different to null
*
* With this setup workQueue won’t actually be used but only
* to check if it’s empty, which should always be the case.
* Any more than permits as value for maximumPoolSize will have
* no effect because at any moment no more than permits calls to
* super.execute() will be allowed by the semaphore.
*/
public class ExecutionBlockingThreadPool extends ThreadPoolExecutor {
private final Semaphore semaphore;
// constructor setting super(…) parameters and initializing semaphore
//
// Below is a bare minimum constructor; using
// corePoolSize = maximumPoolSize = permits
// allows one to use SynchronousQueue because I expect
// none other that isEmpty() to be called on it; it also
// allows for using 0L SECONDS because no more than
// corePoolSize threads should be attempted to create.
public ExecutionBlockingThreadPool(int corePoolSize) {
super(corePoolSize, corePoolSize, 0L, SECONDS, new SynchronousQueue<Runnable>());
semaphore = new Semaphore(corePoolSize, true);
}
public void execute(Runnable command) {
semaphore.acquire();
super.execute(() -> {
try {
command.run();
} finally {
semaphore.release();
}
}
}
}
You can imlement RejectedTaskHandler and get all the rejected tasks when Queue size if full. By default executors have the Abort policy so you can add these task back to the queue from handler or whatever the choice is.
public class ExecutorRejectedTaskHandlerFixedThreadPool {
public static void main(String[] args) throws InterruptedException {
//maximum queue size : 2
BlockingQueue<Runnable> blockingQueue =
new LinkedBlockingQueue<Runnable>(2);
CustomThreadPoolExecutor executor =
new CustomThreadPoolExecutor(4, 5, 5, TimeUnit.SECONDS,
blockingQueue);
RejectedTaskHandler rejectedHandler = new RejectedTaskHandler();
executor.setRejectedExecutionHandler(rejectedHandler);
//submit 20 the tasks for execution
//Note: only 7 tasks(5-max pool size + 2-queue size) will be executed and rest will be rejected as queue will be overflowed
for (int i = 0; i < 20; i++) {
executor.execute(new Task());
}
System.out.println("Thread name " + Thread.currentThread().getName());
}
static class Task implements Runnable {
#Override
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread - " + Thread.currentThread().getName() + " performing it's job");
}
}
static class RejectedTaskHandler implements RejectedExecutionHandler {
#Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.out.println("Task rejected" + r.toString());
}
}
public static class CustomThreadPoolExecutor extends ThreadPoolExecutor {
public CustomThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
#Override
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
}
#Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
}
}
}

Categories