Basically, I have a long task that consists of bunch of sequence sub-tasks as follows:
class Task implements Runnable
{
private Foo foo;
public Task(Foo foo)
{
this.foo = foo;
}
#Override
public void run()
{
doTask1(foo);
doTask2(foo);
doTask3(foo);
doTask4(foo);
// ...
doTaskN(foo);
}
}
What I need is to run only one instance of the Task, and if one Task begins, the other Tasks (if any) should terminate immediately.
I used a single thread executor:
Executor executor = Executors.newSingleThreadExecutor();
and I run the task as:
executor.execute(new Task(foo));
This guarantees that only one task executes at a time, but unfortunately it does not terminate the previous tasks.
However, I decide to use a boolean flag in between each 2 sub-tasks as follows:
class BooleanHolder
{
boolean terminate = false;
}
class Task implements Runnable
{
private Foo foo;
private BooleanHolder bh;
public Task(Foo foo, BooleanHolder bh)
{
this.foo = foo;
this.bh = bh;
}
#Override
public void run()
{
bh.terminate = false;
doTask1(foo);
if(bh.terminate) return;
doTask2(foo);
if(bh.terminate) return;
doTask3(foo);
if(bh.terminate) return;
doTask4(foo);
// ...
if(bh.terminate) return;
doTaskN(foo);
}
}
and use it like this:
BooleanHolder bh = new BooleanHolder();
// ...
bh.terminate = true;
executor.execute(new Task(foo, bh));
However, this seems to be inefficient solution and not thread safe. Do you suggest a better solution?
You should use the ExecutorService interface, instead of Executor, like this:
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<?> future = executor.submit(new Task(foo));
You can then interrupt the running task in order to execute another task through the cancel method:
future.cancel(true);
As #RPT said however, you should structure your tasks in such a way to respond to interrupts, otherwise the interrupt signal will not have any effect. If your task has no operation which throws an InterruptedException, you should manually check the interrupt flag from time to time (similar to what you already did):
#Override
public void run()
{
....
if (Thread.interrupted()) {
// Release resources and end task
}
....
}
By the way, this solves your problem, but does not actually terminate the thread inside ExecutorService.
Related
I have a long running Runnable object and I wanted to provide a more graceful interrupt mechanism than having to call interrupt on the thread the object is running on.
The before code:
public class MyRunnable implements Runnable {
public void run() {
while(!Thread.currentThread().isInterrupted()) {
//do stuff
}
}
}
public class MyClass {
public static void main(String[] args) {
Runnable myRunnable = new MyRunnable();
Thread t = new Thread(myRunnable, "myRunnableThread");
t.start();
//do stuff
t.interrupt();
//do stuff
}
}
And the new code:
public class MyRunnable implements Runnable {
private Thread myThread = null;
public void run() {
myThread = Thread.currentThread();
while(!myThread.isInterrupted()) {
//do stuff
}
}
public void shutdown() {
if (myThread != null) {
myThread.interrupt();
//do other shutdown stuff
}
}
}
public class MyClass {
public static void main(String[] args) {
Runnable myRunnable = new MyRunnable();
Thread t = new Thread(myRunnable, "myRunnableThread");
t.start();
//do stuff
myRunnable.shutdown();
//do stuff
}
}
My question is, are there possible side effects or unknowns that holding a reference to your own thread, and providing limited access to that thread through public methods (as above) could cause? This is assuming that no-one ever calls the run() method directly, that it is always started from a new thread.
And I'm aware that I could use a volatile or atomic Boolean in the run() and shutdown() methods for communicating intent to shutdown, I'm more interested in learning than a solution. But solutions are still welcome!
For me your first approach is much better as less error prone and more "standard". But actually what you try to implement already exists (which proves that it makes sense and that it is not a bad practice but it is not easy to make it properly), it is called FutureTask, instead of shutdown you have cancel(boolean mayInterruptIfRunning) with true as value of mayInterruptIfRunning if you want to interrupt the thread running the task, I quote the javadoc:
Attempts to cancel execution of this task. This attempt will fail if
the task has already completed, has already been cancelled, or could
not be cancelled for some other reason. If successful, and this task
has not started when cancel is called, this task should never run. If
the task has already started, then the mayInterruptIfRunning
parameter determines whether the thread executing this task should be
interrupted in an attempt to stop the task.
For example:
// Task that will only sleep for 1 sec and print a message on interrupted
FutureTask<Void> myRunnable = new FutureTask<>(
new Callable<Void>() {
#Override
public Void call() throws Exception {
try {
System.out.println("Sleep");
Thread.sleep(1_000L);
} catch (InterruptedException e) {
System.out.println("Interrupted !!!");
throw e;
}
return null;
}
}
);
new Thread(myRunnable, "myRunnableThread").start();
// Wait long enough to make sure that myRunnableThread is sleeping
Thread.sleep(500L);
// Cancel the task and interrupt myRunnableThread
myRunnable.cancel(true);
Output:
Sleep
Interrupted !!!
It already has a reference:
Thread.currentThread()
From the javadoc:
Returns a reference to the currently executing thread object.
I have a BlockingQueue that processes work events on a single background thread. Various threads call add to add some work to the queue and a single background thread calls take to get the work and process it one a time. Eventually it may be time to stop the processing of work and I want to make sure that the callers who requested work either get their results or get null indicating their work was not done because the BlockingQueue is shutting down.
How do I cleanly stop accepting new work, the best I can think of is to set BlockingQueue field to null and then catch NullPointerException when add is called. Before setting the field to null I will keep a local copy of the pointer so I can drain it after it has stopped accepting work. I think that will work, but it seems a bit hacky, is there a proper way to do this?
Here is what the code looks like now:
ArrayBlockingQueue<Command> commandQueue =
new ArrayBlockingQueue<Command>(100, true);
public boolean addToQueue(Command command) {
try {
return commandQueue.add(command);
} catch (IllegalStateException e) {
return false;
}
}
#Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
Command command = commandQueue.take();
// ... work happens here
// result is sent back to caller
command.provideResponseData(response);
}
} catch (InterruptedException e) {
// Break out of the loop and stop
}
// TODO: stop accepting any new work, drain the queue of existing work
// and provide null responses
}
Rather than work with BlockingQueue and a worker thread, consider using a single-thread ThreadPoolExecutor. Something like this:
private class CommandRunner implements Runnable {
public CommandRunner(Command command) {
this.command = command;
}
public void run() {
// ... work happens here
// result is sent back to caller
command.provideResponseData(response);
}
}
private ExecutorService commandExecutor = Executors.newSingleThreadExecutor();
public boolean addToQueue(Command command) {
commandExecutor.submit(new CommandRunner(command));
}
And then your shutdown methods can delegate to the executor.
As mentioned before, use an ExecutorService or ThreadPool, but submit Callables instead of mere Runnables. Have your worker threads observe some stop signal (maybe an AtomicBoolean visible to all of them). If the flag has been set, make the Callables return a special value to indicate that nothing was done. Callers must retain the Future returned by submit to get the Callable's result.
Maybe I should elaborate some more. If you are currently using Runnables, maybe wrap them in Callables and, in call, check the stop flag. If you set the stop flag before you call ExecutorService.shutdown, it will complete the current job normally, but effectively cancel all remaining jobs, therefore draining the remaining queue fast. If you do not shut down, you can even reuse the ExecutorService after resetting the stop flag.
static enum EResult {
Cancelled, Completed
}
static abstract class MyCallable implements Callable<EResult> {
Runnable runner;
public MyCallable( Runnable runner) {
super();
this.runner = runner;
}
}
static AtomicBoolean cancelled = new AtomicBoolean( false);
static void main( String[] argv) {
Runnable runnable = new Runnable() {
#Override
public void run() {
System.out.println( "Done");
}
};
Callable<EResult> callable = new MyCallable( runnable) {
#Override
public EResult call() throws Exception {
if ( cancelled.get()) {
return EResult.Cancelled;
}
runner.run();
return EResult.Completed;
}
};
ExecutorService executorService = Executors.newFixedThreadPool( 1);
// while submitting jobs, change cancelled at some point
Future<EResult> future = executorService.submit( callable);
try {
EResult completeOrNot = future.get();
System.out.println( "result: " + completeOrNot);
} catch ( InterruptedException e) {
e.printStackTrace();
} catch ( ExecutionException e) {
e.printStackTrace();
}
}
For example if I have thread A and thread B. Thread A is my main thread where most of the application runs but when I need a value fetched from MySQL or another external source I create a new thread (thread B).
What is the best way of returning the value from thread B to thread A for further processing without causing thread A to wait until the value is available?
If you have a single task that needs to be done, you can use a Future and have the other Thread poll the (non-blocking) isDone() method whenever it is convenient.
If that task is executed frequently or you have many tasks to execute, using a ConcurrentLinkedQueue might be a better idea, which also comes in a variant that supports blocking till a result is delivered as LinkedBlockingQueue. Again: polling on the list whenever it is convenient will do the trick.
If you do not want to poll, you can instead work with a callback-functionality. For example if you use a Swing GUI, you can have the DB thread call invokeLater from the SwingUtilities class, so processing the request is done on the main Swing thread at the next possible time.
This is based on the EventQueue class, which might be more convenient to use in certain other scenarios.
Use a Queue, A will periodically poll the queue, B can put values to queue asynchroneously
You can use ScheduledThreadPoolExecutor which will return Future and you dont need to wait.
Sample Usage (From java Docs on Future)
interface ArchiveSearcher { String search(String target); }
class App {
ExecutorService executor = ...
ArchiveSearcher searcher = ...
void showSearch(final String target)
throws InterruptedException {
Future<String> future
= executor.submit(new Callable<String>() {
public String call() {
return searcher.search(target);
}});
displayOtherThings(); // do other things while searching
try {
displayText(future.get()); // use future
} catch (ExecutionException ex) { cleanup(); return; }
}
}
Same can be achieved from Future task too(visit above link, example are from there only)
The FutureTask class is an implementation of Future that implements Runnable, and so may be executed by an Executor. For example, the above construction with submit could be replaced by:
FutureTask<String> future =
new FutureTask<String>(new Callable<String>() {
public String call() {
return searcher.search(target);
}});
executor.execute(future);
For thread B, declare a class that implements Runnable. For example:
public class MyClass implements Runnable
{
private String input = null;
private String output = null;
public MyClass(String input)
{
this.input = input;
}
public String getOutput()
{
return output;
}
public void run()
{
output = func(input);
}
}
In thread A (which is your main thread), start thread B, and wait for it to complete only where you actually need its output. For example:
public String myFunc(String input) throws Exception
{
MyClass object = new MyClass(input);
Thread thread = new Thread(object);
thread.start();
// Do whatever you wanna do...
// ...
// ...
// And when you need the thread's output:
thread.join();
return object.getOutput();
}
If you don't want to deal with executors, just create a FutureTask and pass it to a new thread.
FutureTask<String> f = new FutureTask<String>(new Callable<String>() {
#Override
public String call() {
return "";
}
});
new Thread(f).start();
while (Thread.currentThread().isInterrupted()) {
if (f.isDone()) {
System.out.println(f.get());
break;
}
//do smth else
}
Organize your main thread as an event loop:
BlockingQueue<Runnable> eventQueue=
new LinkedBlockingQueue<>();
for (;;) {
Runnable nextEvent=eventQueue.take();
nextEvent.run();
}
Thread B:
Result r=fetchFromDB();
eventQueue.put(new ResultHandler(r));
where ResultHandler is a Runnable which knows how to handle the result.
I have two tasks: The first task (work) is reoccurring and the second task (cleanup) is releases some resources. The cleanup task should be run exactly once after the reoccurring work task has completed and will not be run again.
My first instinct was something like this:
ScheduledExecutorService service = ...;
ScheduledFuture<?> future = service.scheduleAtFixedRate(work, ...);
// other stuff happens
future.cancel(false);
cleanup.run();
The problem here is that cancel() returns immediately. So if work happens to be running, then cleanup will overlap it.
Ideally I would use something like Guava's Futures.addCallback(ListenableFuture future, FutureCallback callback). (Guava 15 may have something like that).
In the meantime, how can fire a callback when future is cancelled and work no longer running?
This is the solution that I've come up with. It seems to be pretty simple, but I still assume there's a more common and/or elegant solution out there. I'd really like to see one in a library like Guava...
First I create a wrapper to impose mutual exclusion on my Runnables:
private static final class SynchronizedRunnable implements Runnable {
private final Object monitor;
private final Runnable delegate;
private SynchronizedRunnable(Object monitor, Runnable delegate) {
this.monitor = monitor;
this.delegate = delegate;
}
#Override
public void run() {
synchronized (monitor) {
delegate.run();
}
}
}
Then I create a wrapper to fire my callback on successful invokations of cancel:
private static final class FutureWithCancelCallback<V> extends ForwardingFuture.SimpleForwardingFuture<V> {
private final Runnable callback;
private FutureWithCancelCallback(Future<V> delegate, Runnable callback) {
super(delegate);
this.callback = callback;
}
#Override
public boolean cancel(boolean mayInterruptIfRunning) {
boolean cancelled = super.cancel(mayInterruptIfRunning);
if (cancelled) {
callback.run();
}
return cancelled;
}
}
Then I roll it all together in my own method:
private Future<?> scheduleWithFixedDelayAndCallback(ScheduledExecutorService service, Runnable work, long initialDelay, long delay, TimeUnit unit, Runnable cleanup) {
Object monitor = new Object();
Runnable monitoredWork = new SynchronizedRunnable(monitor, work);
Runnable monitoredCleanup = new SynchronizedRunnable(monitor, cleanup);
Future<?> rawFuture = service.scheduleAtFixedRate(monitoredWork, initialDelay, delay, unit);
Future<?> wrappedFuture = new FutureWithCancelCallback(rawFuture, monitoredCleanup);
return wrappedFuture;
}
I'll give it another shot then. Either you may enhance the command or you may wrap the executed Runnable/Callable. Look at this:
public static class RunnableWrapper implements Runnable {
private final Runnable original;
private final Lock lock = new ReentrantLock();
public RunnableWrapper(Runnable original) {
this.original = original;
}
public void run() {
lock.lock();
try {
this.original.run();
} finally {
lock.unlock();
}
}
public void awaitTermination() {
lock.lock();
try {
} finally {
lock.unlock();
}
}
}
So you can change your code to
ScheduledExecutorService service = ...;
RunnableWrapper wrapper = new RunnableWrapper(work);
ScheduledFuture<?> future = service.scheduleAtFixedRate(wrapper, ...);
// other stuff happens
future.cancel(false);
wrapper.awaitTermination();
cleanup.run();
After calling cancel, either work is no longer running and awaitTermination() returns immediately, or it is running and awaitTermination() blocks until it's done.
Why don't you do
// other stuff happens
future.cancel(false);
service.shutdown();
service.awaitTermination(1, TimeUnit.DAYS);
cleanup.run();
This will tell your executor service to shutdown, thus allowing you to wait for the possibly running work to be finished.
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.