我想恢复被打断的线程的工作,请让我知道一些可能的解决方案。
class RunnableDemo implements Runnable
{
public void run()
{
while(thread.isInterrupted())
{
try{}
catch(Exception e){ //exception caught}
}
}
}
如果捕获到异常,则线程被中断,但即使遇到异常,我也希望线程继续工作,所以请建议我一些方法来解决这个问题。
提前致谢
答案 0 :(得分:5)
线程中断是您在编写线程时选择服从的内容。因此,如果您不希望自己的线程被中断,请不要检查中断状态并继续执行。
你需要try / catch语句(关于线程中断)的唯一一次是调用抛出InterruptedException
的阻塞方法。然后,您需要避免让该异常停止您的线程的工作。
当然......你应该考虑一下这是否是一种合适的行为方式。线程中断是一个有用的东西,选择不遵守它可能会让你的代码用户烦恼。
答案 1 :(得分:1)
我已经编写了一个可重用的代码来获取此功能,其中线程可以暂停和恢复。请在下面找到代码。您可以扩展PausableTask并覆盖task()方法:
public abstract class PausableTask implements Runnable{
private ExecutorService executor = Executors.newSingleThreadExecutor();
private Future<?> publisher;
protected volatile int counter;
private void someJob() {
System.out.println("Job Done :- " + counter);
}
abstract void task();
@Override
public void run() {
while(!Thread.currentThread().interrupted()){
task();
}
}
public void start(){
publisher = executor.submit(this);
}
public void pause() {
publisher.cancel(true);
}
public void resume() {
start();
}
public void stop() {
executor.shutdownNow();
}
}
希望这会有所帮助。有关详细信息,请查看此链接或在评论部分给我留言。 http://handling-thread.blogspot.co.uk/2012/05/pause-and-resume-thread.html
答案 2 :(得分:1)
正如其他人已经说过的那样,通常中断是取消任务的正确方法。如果您确实需要实现不可取消的任务,那么至少确保在完成不可中断的工作后恢复线程的中断状态:
public void run() {
boolean interrupted = false;
try {
while (true) {
try {
callInterruptibleMethod();
} catch (InterruptedException ex) {
interrupted = true;
// fall through and retry
}
}
} finally {
if (interrupted) {
// restore interruption state
Thread.currentThread().interrupt();
}
}
}
答案 3 :(得分:0)
线程get只在有人调用该线程的interrupt()方法时被中断,而不是因为你正在考虑运行你的线程时抛出了一些其他的随机异常。
当调用线程的interrupt()方法时,如果线程处于阻塞操作的中间(例如IO读取),则会在线程中抛出InterruptedException。
当抛出InterruptedException时你应该知道被中断的状态被清除,所以下次你在你的线程中调用isInterrupted()会给你假(即使你只是cauth the InterruptedException)
编写线程时请记住这一点。如果你不明白我在谈论停止编码多线程,那就读一些关于java中并发性的书。
答案 4 :(得分:0)
一个警告:如果您的线程在调用第三方库时处理InterruptedException,那么您不一定知道库对它的反应(即,它是否使库对象处于某种状态时)你的程序继续使用它们是否有意义?)
一些开发人员(包括一些库开发人员)错误地认为中断意味着“关闭程序”,他们担心的只是关闭文件等;而不是关于图书馆是否可以继续使用。
尝试看看,但是如果你正在编写代码来控制航天器或核反应堆或其他东西,那么你可能想做一些额外的工作来真正找出这个库的作用。