方案
我有这个课,让我们说Foo
,其唯一的工作是顺序执行一组任务。听起来很简单吧?好吧,所有这些任务都是在他们自己的单独的线程中执行的。它不是简单地在每个任务上调用Thread.join()
来确保顺序执行,而是使用ReentrantLock
和Condition
。例如,
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;
}
}
完成每项任务后,waitForNotification()
被调用并等待另一个课程,比如Bar
,唤醒它。 Bar
的唯一作业是处理响应,通知应用程序任务是传递还是失败。话虽如此,它将做两件事之一:
getTask().cancel
)getCondition().signal
)第2项工作正常,但第1项不适用 。例如,
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();
}
}
}
而不是取消线程,它似乎中断它,这导致Foo
继续执行。很抱歉,但是我想给你们一个清晰的画面。有什么建议吗?
答案 0 :(得分:1)
除非任务在中断时停止,否则该标志将被设置并保持设置,直到任务结束或决定停止。
可能重复http://www.google.co.uk/search?q=how+do+I+stop+a+thread+in+Java 28,000,000条结果。
答案 1 :(得分:1)
AFAIK,线程不支持开箱即用“取消”的概念。当线程中断时,您必须在逻辑中烘焙“取消”您的特定任务。这通常通过在运行任务/作业时检查线程的中断状态来完成,如果状态已设置为true(在调用中断时会发生这种情况),则会彻底退出。
A sample snippet 可能帮助您解决问题。另请阅读shutting down threads cleanly。