Issue in Future.cancel() method - java

I have a below runnable task which is run by using ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1)); This ensures that there will be only one waiting task in the queue.
protected void waitAndSweep(final String symbol) {
try {
runnable = new Runnable() {
#Override
public void run() {
try {
// long sweepTime = symbolInfo.getSweepTime(symbol);
// long timeSinceLastSweep = System.currentTimeMillis() - lastSliceSentTime;
boolean sliceDone = Quant.equals(wave.getCommitedQuantity() % getSliceQuantity(),0);
if(sliceDone){
long timeSinceLastSliceQtySent = lastSliceSentTime == 0 ? getInterval() : System.currentTimeMillis() - lastSliceSentTime;
long waitTime = timeSinceLastSliceQtySent >= getInterval() ? 0 : getInterval() - timeSinceLastSliceQtySent;
logTradeEvent("waitAndSweep", symbol, "waittime: " + waitTime);
if (waitTime > 0){
Thread.sleep(waitTime);
}
}
callSweep(symbol);
} catch(InterruptedException ie){
ie.printStackTrace();
}
catch (Exception e) {
logEvent(StrategyEntry.ERROR, "waitAndSweep", symbol,
"Exception caught...", e);
}
}
};
self = threadPoolExecutor.submit(runnable);
}catch(RejectedExecutionException re){
/* this exception will be thrown when wait and sweep is called more than twice.
* threadPoolExecutor can have one running task and one waiting task.
* */
System.out.print(re);
}catch (Exception e) {
logEvent(StrategyEntry.ERROR, "waitAndSweep", symbol,
"Exception caught...", e);
}
}
Consider the caller A :
private void callerA(){
waitandsweep();
waitandsweep();}
this craetes two task one will be running and another waiting in the queue.
Consider the callerB:
private void callerB(){
self.cancel(true);
waitandsweep();}
Expecting callerB to cancel all the tasks invoked by A.
Actually it is not happening.. task invoked by caller B is getting rejected because already one task is waiting in the queue. Can you please tell why this behaviour happens?
edit 1 : How to cancel running task of executor?

The problem is, that Future.cancel(boolean) doesn't remove the task from the queue. The Task will not be executed, once it will be pulled by the Executor but until then its still in the queue
try to use threadPoolExecutor.purge(); right after cancel(); it will try to remove the canceled tasks
cancelling a running Task is not that easy, you could try following:
call cancel(true); it will set Thread.interrupted() to true. Now in your Task check on some steps that value and so you can decide to skip next steps of your task

Related

What is the prod and cons of following implementation for waiting before execution when thread queue is full? [duplicate]

This question already has answers here:
ThreadPoolExecutor Block When its Queue Is Full?
(10 answers)
Closed 3 months ago.
We have a large text file in which each line requires intensive process. The design is to have a class that reads the file and delegates the processing of each line to a thread, via thread pool. The file reader class should be blocked from reading the next line once there is no free thread in the pool to do the processing. So i need a blocking thread pool
In the current implementation ThreadPoolExecutor.submit() and ThreadPoolExecutor.execute() methods throw RejectedExecutionException exception after the configured # of threads get busy as i showed in code snippet below.
public class BlockingTp {
public static void main(String[] args) {
BlockingQueue blockingQueue = new ArrayBlockingQueue(3);
ThreadPoolExecutor executorService=
new ThreadPoolExecutor(1, 3, 30, TimeUnit.SECONDS, blockingQueue);
int Jobs = 10;
System.out.println("Starting application with " + Jobs + " jobs");
for (int i = 1; i <= Jobs; i++)
try {
executorService.submit(new WorkerThread(i));
System.out.println("job added " + (i));
} catch (RejectedExecutionException e) {
System.err.println("RejectedExecutionException");
}
}
}
class WorkerThread implements Runnable {
int job;
public WorkerThread(int job) {
this.job = job;
}
public void run() {
try {
Thread.sleep(1000);
} catch (Exception excep) {
}
}
}
Output of above program is
Starting application to add 10 jobs
Added job #1
Added job #2
Added job #3
Added job #4
Added job #5
Added job #6
RejectedExecutionException
RejectedExecutionException
RejectedExecutionException
RejectedExecutionException
Can some one throw some light i.e how i can implement blocking thread pool.
Can some one throw some light i.e how i can implement blocking thread pool.
You need to set a rejection execution handler on your executor service. When the thread goes to put the job into the executor, it will block until there is space in the blocking queue.
BlockingQueue arrayBlockingQueue = new ArrayBlockingQueue(3);
ThreadPoolExecutor executorService =
new ThreadPoolExecutor(1, 3, 30, TimeUnit.SECONDS, arrayBlockingQueue);
// when the blocking queue is full, this tries to put into the queue which blocks
executorService.setRejectedExecutionHandler(new RejectedExecutionHandler() {
#Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
// block until there's room
executor.getQueue().put(r);
// check afterwards and throw if pool shutdown
if (executor.isShutdown()) {
throw new RejectedExecutionException(
"Task " + r + " rejected from " + executor);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RejectedExecutionException("Producer interrupted", e);
}
}
});
So instead of the TRE throwing a RejectedExecutionException, it will call the rejection handler which will in turn try to put the job back on the queue. This blocks the caller.
Lets have a look at your code again:
for (int i = 1; i <= Jobs; i++)
try {
tpExe.submit(new WorkerThread(i));
System.out.println("job added " + (i));
} catch (RejectedExecutionException e) {
System.err.println("RejectedExecutionException");
}
So - when you try to submit, and the pool is busy, that exception is thrown. If you want to wrap around that, it could look like:
public void yourSubmit(Runnable whatever) {
boolean submitted = false;
while (! submitted ) {
try {
tpExe.submit(new WorkerThread(whatever));
submitted = true;
} catch (RejectedExecutionException re) {
// all threads busy ... so wait some time
Thread.sleep(1000);
}
In other words: use that exception as "marker" that submits are currently not possible.
You can use semaphore for to control the resource.Reader will read and create asynchronous task by acquiring semaphore.If every thread is busy the reader thread will wait till thread is available.
public class MyExecutor {
private final Executor exec;
private final Semaphore semaphore;
public BoundedExecutor(Executor exec, int bound) {
this.exec = exec;
this.semaphore = new Semaphore(bound);
}
public void submitTask(final Runnable command)
throws InterruptedException, RejectedExecutionException {
semaphore.acquire();
try {
exec.execute(new Runnable() {
public void run() {
try {
command.run();
} finally {
semaphore.release();
}
}
});
} catch (RejectedExecutionException e) {
semaphore.release();
throw e;
}
}
}
Here is a RejectedExecutionHandler that supports the desired behavior. Unlike other implementations, it does not interact with the queue directly so it should be compatible with all Executor implementations and will not deadlock.
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.BiFunction;
import static com.github.cowwoc.requirements.DefaultRequirements.assertThat;
import static com.github.cowwoc.requirements.DefaultRequirements.requireThat;
/**
* Applies a different rejection policy depending on the thread that requested execution.
*/
public final class ThreadDependantRejectionHandler implements RejectedExecutionHandler
{
private final ThreadLocal<Integer> numberOfRejections = ThreadLocal.withInitial(() -> 0);
private final BiFunction<Thread, Executor, Action> threadToAction;
/**
* #param threadToAction indicates what action a thread should take when execution is rejected
* #throws NullPointerException if {#code threadToAction} is null
*/
public ThreadDependantRejectionHandler(BiFunction<Thread, Executor, Action> threadToAction)
{
requireThat(threadToAction, "threadToAction").isNotNull();
this.threadToAction = threadToAction;
}
#SuppressWarnings("BusyWait")
#Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor)
{
if (executor.isShutdown())
return;
Thread currentThread = Thread.currentThread();
Action action = threadToAction.apply(currentThread, executor);
if (action == Action.RUN)
{
r.run();
return;
}
if (action == Action.REJECT)
{
throw new RejectedExecutionException("The thread pool queue is full and the current thread is not " +
"allowed to block or run the task");
}
assertThat(action, "action").isEqualTo(Action.BLOCK);
int numberOfRejections = this.numberOfRejections.get();
++numberOfRejections;
this.numberOfRejections.set(numberOfRejections);
if (numberOfRejections > 1)
return;
try
{
ThreadLocalRandom random = ThreadLocalRandom.current();
while (!executor.isShutdown())
{
try
{
Thread.sleep(random.nextInt(10, 1001));
}
catch (InterruptedException e)
{
throw new WrappingException(e);
}
executor.submit(r);
numberOfRejections = this.numberOfRejections.get();
if (numberOfRejections == 1)
{
// Task was accepted, or executor has shut down
return;
}
// Task was rejected, reset the counter and try again.
numberOfRejections = 1;
this.numberOfRejections.set(numberOfRejections);
}
throw new RejectedExecutionException("Task " + r + " rejected from " + executor + " because " +
"the executor has been shut down");
}
finally
{
this.numberOfRejections.set(0);
}
}
public enum Action
{
/**
* The thread should run the task directly instead of waiting for the executor.
*/
RUN,
/**
* The thread should block until the executor is ready to run the task.
*/
BLOCK,
/**
* The thread should reject execution of the task.
*/
REJECT
}
}
This works for me.
class handler implements RejectedExecutionHandler{
#Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
executor.getQueue().put(r);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

Android Thread is not timing out on wait/notify method

The timeout on b.wait(1000) instruction is not executing after 1 second.
I will appreciate some help on how to execute the timeout on the wait() method.
protected void onCreate(Bundle savedInstanceState) {
ThreadB b = new ThreadB();
b.start();
synchronized (b) {
try {
long start = System.currentTimeMillis();
Log.i(TAG, "Before Wait has started "+start);
b.wait(1000);
long finish = System.currentTimeMillis();
Log.i(TAG, "After Wait has finished "+finish);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
}
class ThreadB extends Thread {
#Override
public void run() {
synchronized (this) {
long start = System.currentTimeMillis();
Log.i(TAG, "*** Thread Start "+start);
Random ran = new Random();
for (int i = 0; i < 1E7; i++) {
Math.sin(ran.nextDouble());
}
long finish = System.currentTimeMillis();
Log.i(TAG, "*** Thread Finish "+finish);
notify();
}
}
}
Your program has a "race" to acquire the lock on the ThreadB object. If the main thread wins the race, the timeout logic works. If the new thread wins, the main thread has to wait for the new thread to finish so that it can grab the lock, and after that then it will call Object.wait and sleep for 1 second.
One quick fix is to make sure that the main thread has the lock before the new thread starts:
ThreadB b = new ThreadB();
synchronized (b) {
b.start();
try {
long start = System.currentTimeMillis();
....
}
}
A better solution is to start using the higher level concepts in the java.util.concurrent library. Instead of creating a new thread, send a task to be computed by a thread pool:
ExecutorService threadPool = Executors.newFixedThreadPool(1);
Future<?> submit = threadPool.submit(() -> {
// ThreadB computation logic
});
and then specify a timeout to wait for its results:
try {
submit.get(1, TimeUnit.SECONDS);
} catch (Exception e) {
// handle timeout, interruption, exceptions
}
Note that on Android, it's not a great idea make the main thread block or wait, even if it's for only 1 second.

Use semaphore to stop thread in timer from execution

I have the following java code, that uses the ScheduledExecuterService. Basically, there are two important calls made in this method: 1. the integrationMonitor.Processor(...) and 2. the runIntegrationSynching() methods.
The scheduler will make sure that these methods execute according to the time interval. Recently however, I've had the problem where processing of these two methods are very long. If the user then sets the timer interval to too low, the next processing cycle will start, even before the previous one finished.
Someone here suggested I use semaphores to do the synchronization, and I did - it works for one of my test cases, but not the other one.
I am using a semaphore to prevent a new schedule cycle to start, if a previous one is still busy. How can I know when a thread finished so that I can release the semaphore?
Here is the code:
static Semaphore semaphore = new Semaphore(1);
final ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
try {
semaphore.acquire();
catch(InterruptedException e1) {}
runIntegrationSynching();
try {
semaphore.release();
} catch(InterruptedException e1) {}
Thread thread = new Thread(){
public void run(){
IntegrationMonitor intgrationMonitor = new IntegrationMonitor();
try {
semaphore.acquire();
} catch(InterruptedException e1) {}
intgrationMonitor.Processing(configXML, rcHost, alarmMonitorMap, blocker);
try {
semaphore.release();
} catch(InterruptedException e1) {}
if(intgrationMonitor != null){
intgrationMonitor = null;
}
}
};
LOGGER.info("Attempting to start the thread for RC " + rcHost + ". Thread ID:" + thread.getId());
thread.start();
}
},2,2,TimeUnit.MINUTES);

How to implement blocking thread pool executor? [duplicate]

This question already has answers here:
ThreadPoolExecutor Block When its Queue Is Full?
(10 answers)
Closed 3 months ago.
We have a large text file in which each line requires intensive process. The design is to have a class that reads the file and delegates the processing of each line to a thread, via thread pool. The file reader class should be blocked from reading the next line once there is no free thread in the pool to do the processing. So i need a blocking thread pool
In the current implementation ThreadPoolExecutor.submit() and ThreadPoolExecutor.execute() methods throw RejectedExecutionException exception after the configured # of threads get busy as i showed in code snippet below.
public class BlockingTp {
public static void main(String[] args) {
BlockingQueue blockingQueue = new ArrayBlockingQueue(3);
ThreadPoolExecutor executorService=
new ThreadPoolExecutor(1, 3, 30, TimeUnit.SECONDS, blockingQueue);
int Jobs = 10;
System.out.println("Starting application with " + Jobs + " jobs");
for (int i = 1; i <= Jobs; i++)
try {
executorService.submit(new WorkerThread(i));
System.out.println("job added " + (i));
} catch (RejectedExecutionException e) {
System.err.println("RejectedExecutionException");
}
}
}
class WorkerThread implements Runnable {
int job;
public WorkerThread(int job) {
this.job = job;
}
public void run() {
try {
Thread.sleep(1000);
} catch (Exception excep) {
}
}
}
Output of above program is
Starting application to add 10 jobs
Added job #1
Added job #2
Added job #3
Added job #4
Added job #5
Added job #6
RejectedExecutionException
RejectedExecutionException
RejectedExecutionException
RejectedExecutionException
Can some one throw some light i.e how i can implement blocking thread pool.
Can some one throw some light i.e how i can implement blocking thread pool.
You need to set a rejection execution handler on your executor service. When the thread goes to put the job into the executor, it will block until there is space in the blocking queue.
BlockingQueue arrayBlockingQueue = new ArrayBlockingQueue(3);
ThreadPoolExecutor executorService =
new ThreadPoolExecutor(1, 3, 30, TimeUnit.SECONDS, arrayBlockingQueue);
// when the blocking queue is full, this tries to put into the queue which blocks
executorService.setRejectedExecutionHandler(new RejectedExecutionHandler() {
#Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
// block until there's room
executor.getQueue().put(r);
// check afterwards and throw if pool shutdown
if (executor.isShutdown()) {
throw new RejectedExecutionException(
"Task " + r + " rejected from " + executor);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RejectedExecutionException("Producer interrupted", e);
}
}
});
So instead of the TRE throwing a RejectedExecutionException, it will call the rejection handler which will in turn try to put the job back on the queue. This blocks the caller.
Lets have a look at your code again:
for (int i = 1; i <= Jobs; i++)
try {
tpExe.submit(new WorkerThread(i));
System.out.println("job added " + (i));
} catch (RejectedExecutionException e) {
System.err.println("RejectedExecutionException");
}
So - when you try to submit, and the pool is busy, that exception is thrown. If you want to wrap around that, it could look like:
public void yourSubmit(Runnable whatever) {
boolean submitted = false;
while (! submitted ) {
try {
tpExe.submit(new WorkerThread(whatever));
submitted = true;
} catch (RejectedExecutionException re) {
// all threads busy ... so wait some time
Thread.sleep(1000);
}
In other words: use that exception as "marker" that submits are currently not possible.
You can use semaphore for to control the resource.Reader will read and create asynchronous task by acquiring semaphore.If every thread is busy the reader thread will wait till thread is available.
public class MyExecutor {
private final Executor exec;
private final Semaphore semaphore;
public BoundedExecutor(Executor exec, int bound) {
this.exec = exec;
this.semaphore = new Semaphore(bound);
}
public void submitTask(final Runnable command)
throws InterruptedException, RejectedExecutionException {
semaphore.acquire();
try {
exec.execute(new Runnable() {
public void run() {
try {
command.run();
} finally {
semaphore.release();
}
}
});
} catch (RejectedExecutionException e) {
semaphore.release();
throw e;
}
}
}
Here is a RejectedExecutionHandler that supports the desired behavior. Unlike other implementations, it does not interact with the queue directly so it should be compatible with all Executor implementations and will not deadlock.
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.BiFunction;
import static com.github.cowwoc.requirements.DefaultRequirements.assertThat;
import static com.github.cowwoc.requirements.DefaultRequirements.requireThat;
/**
* Applies a different rejection policy depending on the thread that requested execution.
*/
public final class ThreadDependantRejectionHandler implements RejectedExecutionHandler
{
private final ThreadLocal<Integer> numberOfRejections = ThreadLocal.withInitial(() -> 0);
private final BiFunction<Thread, Executor, Action> threadToAction;
/**
* #param threadToAction indicates what action a thread should take when execution is rejected
* #throws NullPointerException if {#code threadToAction} is null
*/
public ThreadDependantRejectionHandler(BiFunction<Thread, Executor, Action> threadToAction)
{
requireThat(threadToAction, "threadToAction").isNotNull();
this.threadToAction = threadToAction;
}
#SuppressWarnings("BusyWait")
#Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor)
{
if (executor.isShutdown())
return;
Thread currentThread = Thread.currentThread();
Action action = threadToAction.apply(currentThread, executor);
if (action == Action.RUN)
{
r.run();
return;
}
if (action == Action.REJECT)
{
throw new RejectedExecutionException("The thread pool queue is full and the current thread is not " +
"allowed to block or run the task");
}
assertThat(action, "action").isEqualTo(Action.BLOCK);
int numberOfRejections = this.numberOfRejections.get();
++numberOfRejections;
this.numberOfRejections.set(numberOfRejections);
if (numberOfRejections > 1)
return;
try
{
ThreadLocalRandom random = ThreadLocalRandom.current();
while (!executor.isShutdown())
{
try
{
Thread.sleep(random.nextInt(10, 1001));
}
catch (InterruptedException e)
{
throw new WrappingException(e);
}
executor.submit(r);
numberOfRejections = this.numberOfRejections.get();
if (numberOfRejections == 1)
{
// Task was accepted, or executor has shut down
return;
}
// Task was rejected, reset the counter and try again.
numberOfRejections = 1;
this.numberOfRejections.set(numberOfRejections);
}
throw new RejectedExecutionException("Task " + r + " rejected from " + executor + " because " +
"the executor has been shut down");
}
finally
{
this.numberOfRejections.set(0);
}
}
public enum Action
{
/**
* The thread should run the task directly instead of waiting for the executor.
*/
RUN,
/**
* The thread should block until the executor is ready to run the task.
*/
BLOCK,
/**
* The thread should reject execution of the task.
*/
REJECT
}
}
This works for me.
class handler implements RejectedExecutionHandler{
#Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
executor.getQueue().put(r);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

Java - Get thread state

I am using ThreadPoolExecutor to run the threads.
ExecutorService executorService = Executors.newCachedThreadPool();
Future<?> future = executorService.submit(new MyRunnable());
Based on some conditions, I need to terminate the long running thread and start the same thread instance again(for some cleanup operations).
Since I have a future object of the thread, I can easily check if it is still running.
future.isDone()
If it is running, I can send a interrupt signal by using
future.cancel(true);
In the MyRunnable class, the interrupt signal is handled. But this condition is checked at the beginning of the loop.
The problem is future.isDone() returns true as soon as interrupt signal is sent. But I need to wait till the thread instance is really completed.
Is there any way to check if the thread is really running/completed?
The Apidoc also mentions that future.isDone() returns true if future.cancel() was called, i.e. it does not always tell you if the task has finished.
To check if the task is finished, you need acces to the Runnable and then you can check if the task has completed or wait for it to complete.
Compare the code below with the output shown beneath it, I think that will give you an idea of your options:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Q21227864 {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
Future<?> future = executorService.submit(new MyRunnable());
sleep(100L);
future.cancel(true);
System.out.println("Future done: " + future.isDone());
sleep(100L);
future.cancel(true);
System.out.println("Future done: " + future.isDone());
sleep(500L);
System.out.println("Future done: " + future.isDone());
System.out.println("---");
MyRunnable mr = new MyRunnable();
future = executorService.submit(mr);
sleep(100L);
future.cancel(true);
System.out.println("Runnable done: " + mr.isDone());
sleep(100L);
System.out.println("Runnable done: " + mr.isDone());
mr.waitForCleanup();
System.out.println("Runnable done: " + mr.isDone());
executorService.shutdownNow();
}
public static void sleep(long timeMs) {
try { Thread.sleep(timeMs); } catch (Exception ignored) {}
}
static class MyRunnable implements Runnable {
final CountDownLatch completed = new CountDownLatch(1);
public void run() {
try {
System.out.println("Sleeping loop");
Thread.sleep(1000L);
System.out.println("Sleeping loop done");
} catch (Exception e) {
System.out.println("Stopped loop: " + e);
}
try {
System.out.println("Sleeping cleanup");
Thread.sleep(300L);
System.out.println("Sleeping cleanup done");
} catch (Exception e) {
System.out.println("Stopped cleanup: " + e);
}
completed.countDown();
}
public boolean isDone() {
return (completed.getCount() == 0);
}
public void waitForCleanup() {
try { completed.await(); } catch (Exception ignored) {}
}
}
}
Output:
Sleeping loop
Future done: true
Stopped loop: java.lang.InterruptedException: sleep interrupted
Sleeping cleanup
Future done: true
Sleeping cleanup done
Future done: true
---
Sleeping loop
Runnable done: false
Stopped loop: java.lang.InterruptedException: sleep interrupted
Sleeping cleanup
Runnable done: false
Sleeping cleanup done
Runnable done: true
I don't think future.isDone() returns true as soon as interrupt signal is sent. All ThreadPoolExecutor tasks are executed via FutureTask.run() method
public class FutureTask<V> implements RunnableFuture<V> {
...
public boolean isDone() {
return state != NEW;
}
public void run() {
...
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call(); <-- this invokes your code
ran = true;
} catch (Throwable ex) {
result = null; <-- if you threw InterruptedException
ran = false;
setException(ex); <-- state changes here
}
if (ran)
set(result); <-- if your code simply returns then state changes here
}
...

Categories