Java 当另一个线程启动时终止该线程
基本上,我有一个很长的任务,由一系列序列子任务组成,如下所示:Java 当另一个线程启动时终止该线程,java,multithreading,synchronization,thread-safety,Java,Multithreading,Synchronization,Thread Safety,基本上,我有一个很长的任务,由一系列序列子任务组成,如下所示: class Task implements Runnable { private Foo foo; public Task(Foo foo) { this.foo = foo; } @Override public void run() { doTask1(foo); doTask2(foo); doTask3
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);
}
}
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);
}
}
我需要的是只运行任务
的一个实例,如果一个任务
开始,另一个任务
将立即终止
我使用了单线程执行器:
Executor executor = Executors.newSingleThreadExecutor();
我以以下方式运行任务:
executor.execute(new Task(foo));
这保证了一次只执行一个任务,但不幸的是,它不会终止以前的任务
但是,我决定在两个子任务之间使用布尔标志,如下所示:
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);
}
}
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);
}
}
然后像这样使用它:
BooleanHolder bh = new BooleanHolder();
// ...
bh.terminate = true;
executor.execute(new Task(foo, bh));
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<?> future = executor.submit(new Task(foo));
然而,这似乎是低效的解决方案,并且不是线程安全的。您是否建议更好的解决方案?您应该使用
ExecutorService
界面,而不是Executor
,如下所示:
BooleanHolder bh = new BooleanHolder();
// ...
bh.terminate = true;
executor.execute(new Task(foo, bh));
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<?> future = executor.submit(new Task(foo));
然而,正如@RPT所说,您应该以这样一种方式来组织任务,以响应中断,否则中断信号将不会产生任何影响。如果您的任务没有引发中断异常的操作,则应不时手动检查中断标志(类似于您已经执行的操作):
顺便说一下,这解决了您的问题,但实际上并没有终止ExecutorService中的线程