我有一个长时间运行的Runnable对象,我想提供一个更优雅的中断机制,而不是在运行该对象的线程上调用中断。
之前的代码:
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
}
}
新代码:
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
}
}
我的问题是,是否存在可能导致对您自己的线程的引用的副作用或未知数,并通过公共方法(如上所述)提供对该线程的有限访问可能会导致?这假设没有人直接调用run()
方法,它总是从新线程开始。
而且我知道我可以在run()
和shutdown()
方法中使用volatile或atomic布尔值来传递关闭意图,我对学习比解决方案更感兴趣。但仍然欢迎解决方案!
答案 0 :(得分:1)
对我来说,你的第一种方法要好得多,因为它不易出错,而且更符合标准"但实际上你试图实现的东西已经存在(这证明它是有意义的并且它不是一个坏习惯,但它并不容易使它正确),它被称为FutureTask
,而不是关闭你有{{如果要中断运行任务的线程,true
的值为mayInterruptIfRunning
{3}},我引用javadoc:
尝试取消执行此任务。如果这种尝试失败了 任务已经完成,已经取消,或者可以 因其他原因不能取消。如果成功,那么这个任务 调用cancel时尚未启动,此任务永远不会运行。如果 任务已经开始,然后是
mayInterruptIfRunning
参数确定执行此任务的线程是否应该是 因试图停止任务而中断。
例如:
// 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);
<强>输出:强>
Sleep
Interrupted !!!
答案 1 :(得分:0)