Reputation: 44250
Scenario
I have this class, let's say Foo
, whose only job is to sequentially execute a set of tasks. Sounds simple, right? Well, all of these tasks are executed in their own separate thread. Instead of simply calling Thread.join()
on each task to ensure sequential execution, it uses a ReentrantLock
and Condition
. For instance,
public class Foo
{
private final Lock lock;
private final Condition condition;
private Future<?> task;
public Foo()
{
lock = new ReentrantLock();
condition = lock.newCondition();
run();
}
/**
* Runs Foo
*/
public void run()
{
Runnable runnable = new Runnable()
{
@Override
public void run()
{
lock.lock();
try
{
// do tasks
}
finally
{
lock.unlock();
}
}
};
// Submit task
task = Executors.newSingleThreadExecutor().submit(runnable);
}
/**
* Blocks execution until signal is received
*/
public void waitForNotification()
{
try
{
condition.await();
}
catch (InterruptedException e)
{
}
}
/**
* Gets the lock
*
* @return Lock
*/
public final Lock getLock()
{
return lock;
}
/**
* Gets the condition
*
* @return Condition
*/
public final Condition getCondition()
{
return condition;
}
/**
* Gets the sender's task
*
* @return Task
*/
public Future<?> getTask()
{
return task;
}
}
After every task, waitForNotification()
is called and waits for another class, let's say Bar
, to wake it up. The only job for Bar
is to handle a response that informs the application whether the task has passed or failed. That being said, it will do one of two things:
getTask().cancel
)getCondition().signal
)Item 2 works just fine, but Item 1 doesn't. For instance,
public class Bar
{
private Foo foo;
// doesn't work!
public void handleFailed()
{
// Cancel task
foo.getTask().cancel(true)
}
public void handlePassed()
{
// Signal waiting Foo
foo.getLock().lock();
try
{
foo.getCondition().signal();
}
finally
{
foo.getLock().unlock();
}
}
}
Instead of cancelling the thread, it just seems to interrupt it, which causes Foo
to continue its execution. Sorry for the verbosity, but I wanted to give you guys a clear picture. Any suggestions?
Upvotes: 0
Views: 1132
Reputation: 23248
AFAIK, threads don't support the notion of "cancelling" out of the box. You have to bake in the logic to "cancel" your specific tasks when your thread is interrupted. This is typically done by checking the interrupt status of the thread when running your task/job and exit out cleanly if the status has been set to true (which happens when you call interrupt).
A sample snippet which might help you out. Also read, shutting down threads cleanly.
Upvotes: 1
Reputation: 533880
Unless the task stops when interrupted, the flag will just be set and remain set until the task ends or decides to stop.
Possible duplicate of http://www.google.co.uk/search?q=how+do+I+stop+a+thread+in+Java 28,000,000 results.
Upvotes: 1