使用评论查看以下代码段:
try {
Thread.sleep(20000); // Foo thread sleeps for 20 seconds
System.out.println("After the sleep statement");
} catch(Exception exc) {
exc.printStackTrace();
}
// It has been 12 seconds since the thread went to sleep and....I interrupt
Foo.interrupt(); // exception gets thrown and the code in the catch block gets executed
有什么办法可以在sleep语句之后执行下一个语句?我想在某个时候唤醒线程并希望它继续工作。对此有什么想法/方法吗?
答案 0 :(得分:1)
不确定这是否是你想要的?
try {
Thread.sleep(20000); // Foo thread sleeps for 20 seconds
System.out.println("After the sleep statement");
} catch(InterruptedException exc) {
System.out.println("Sleep was interrupted");
} catch(Exception exc) {
exc.printStackTrace();
}
sleep()
在被中断时抛出InterruptedException
。因此"Sleep was interrupted"
将打印在interrupt()
上,而"After the sleep statement"
仅在sleep()
设置为睡眠配置20秒后才会被调用。
如果您不关心sleep()
是否正常返回或抛出并继续工作,请用空try-catch
包裹它:
public void interruptibleSleep(long millis) {
try {
Thread.sleep(millis);
} catch(InterruptedException exc) {}
}
然后代替Thread.sleep(20000)
致电interruptibleSleep(20000)
:
interruptibleSleep(20000);
System.out.println("After the sleep statement");
答案 1 :(得分:1)
我觉得你很困惑。这是发生的事情
public void run() {
// This executes as soon as the thread is run
try {
// We decide to sleep for UPTO 20 seconds
Thread.sleep(20000);
// Code here executes ONLY if we managed to sleep for 20 seconds without
// interruption
} catch(InterruptedException exc) {
// Code here executes ONLY if we were interrupted
} catch(Exception exc) {
// This shouldn't ever execute in theory
}
// Code here ALWAYS executes after the sleeping (and ONE of the two blocks)
// whether or not it was interrupted.
}
答案 2 :(得分:1)
中断是一个线程的指示,它应该停止它正在做的事情并做其他事情。由程序员决定线程如何响应中断,但线程终止是很常见的。这是本课中强调的用法。
可靠地停止和启动线程是设计并发应用程序的重要部分。即使你可以重新利用中断来做任何你想做的事情,如果你为了它最常见的目的而留下中断,你的代码将更可靠,更容易维护 - 请求线程退出。如果用户在20秒超时完成之前决定关闭应用程序,那么您可能希望这样做。
那么如何解决原始问题 - 允许一个线程向另一个线程表明是时候开始工作了。下面的类显示了如何使用CountDownLatch来解决此问题。
新的Foo:
class Foo extends Thread
{
CountDownLatch latch = new CountDownLatch(1);
@Override
public void run()
{
try
{
boolean early = latch.await(20, TimeUnit.SECONDS);
System.out.println("Doing work " + (early ? "right away" : "after delay"));
// do real work here...
}
catch (InterruptedException e)
{
System.out.println("Interrupt detected. Exiting thread...");
}
}
public void goAhead()
{
latch.countDown();
}
}
我们摆脱了“Sleep”并用对latch对象的await方法的调用替换它。要使foo工作,请调用:
foo.goAhead(); // prints out "Doing work right away"
这会导致闩锁倒计时。对“await”的调用将立即退出而不抛出异常并返回true。
要关闭foo,请使用:
foo.interrupt(); // prints out "Interrupt detected..."
这将导致等待抛出InterruptedException,就像睡眠一样。
或什么也不做。等待20秒后超时的调用,不会抛出异常并返回false。 Foo打印出“延迟后做工作”
这种设计的一个长期优势是,当您“正在工作”时,您可能需要调用其他阻止方法。中断仍可用于中断其中任何一个,并帮助您可靠地关闭线程以响应意外事件。