假定场景
线程1在进行耗时任务,例如从网络读取数据。我们的期望时间是30s内结束,如果超过30s则直接停止该线程,并开始执行JVM退出流程。
如何实现该种场景?
思路1
直接对线程1执行interupt()方法。可以这样做,但是要注意使用场景,摘自interupt()方法的javadoc:
If this thread is blocked in an invocation of the
wait()
,wait(long)
, orwait(long, int)
methods of theObject
class, or of thejoin()
,join(long)
,join(long, int)
,sleep(long)
, orsleep(long, int)
, methods of this class, then its interrupt status will be cleared and it will receive anInterruptedException
.
If this thread is blocked in an I/O operation upon anInterruptibleChannel
then the channel will be closed, the thread's interrupt status will be set, and the thread will receive aClosedByInterruptException
.
If this thread is blocked in aSelector
then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector'swakeup
method were invoked.
If none of the previous conditions hold then this thread's interrupt status will be set.
思路2
调用线程的stop方法
不推荐!!stop方法已被标记为deprecated
,随时可能被移除,且有很多已知问题。
思路3
实现方式:以如下代码为例,main ---fork1---> executeThread ---fork2---> runner(daemon)
。当fork2
成功后,通过runner.join()
,使得executeThread
开始等待runner
的结束。此时如果main线程执行executeThread.interupt()
,则executeThread
抛出InterruptedException
并退出,由于runner是daemon线程,在main执行完后没有非daemon属性的用户线程在执行了,JVM开始执行退出流程。
思路3样例代码:
main
public static void main(String[] args) {
ThreadService service = new ThreadService();
long start = System.currentTimeMillis();
service.execute(() -> {
//load a very heavy resource.
/*while (true) {
}*/
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
service.shutdown(10000);
long end = System.currentTimeMillis();
System.out.println(end - start);
}
ThreadService.java
public class ThreadService {
private Thread executeThread;
private boolean finished = false;
public void execute(Runnable task) {
executeThread = new Thread() {
@Override
public void run() {
Thread runner = new Thread(task);
runner.setDaemon(true);
runner.start();
try {
runner.join();
finished = true;
} catch (InterruptedException e) {
//e.printStackTrace();
}
}
};
executeThread.start();
}
public void shutdown(long mills) {
long currentTime = System.currentTimeMillis();
while (!finished) {
if ((System.currentTimeMillis() - currentTime) >= mills) {
System.out.println("任务超时,需要结束他!");
executeThread.interrupt();
break;
}
try {
executeThread.sleep(1);
} catch (InterruptedException e) {
System.out.println("执行线程被打断!");
break;
}
}
finished = false;
}
}
网友评论