我正在学习Java并发,并尝试了Java教程中的一个示例,并进行了一些实验(尝试捕获异常)。
public class SleepMessages {
public static void main(String args[]) {
String importantInfo[] = {
"Mares eat oats",
"Does eat oats",
"Little lambs eat ivy",
"A kid will eat ivy too"
};
try { // my experiment
for (int i = 0; i < importantInfo.length; i++) {
Thread.sleep(4000);
System.out.println(importantInfo[i]);
}
}
catch (InterruptedException ie) {
System.out.println("caught InterruptedException");
}
}
}
我尝试向外发送一个中断信号,通过&#34; kill -2 $ PID&#34;。
我预计当处理处于休眠状态时,信号会导致Thread.sleep()抛出异常,然后我就可以捕获它,但实际上并没有!
有人可以解释为什么吗? (我想知道它可能是我发送信号的方式(kill -2)是不正确的。)
答案 0 :(得分:3)
从外部处理SIGINT信号的方法是在您的应用中注册shutdown hook:
public class Main
{
public static void main(final String[] args) throws InterruptedException
{
Runtime.getRuntime().addShutdownHook(new Thread()
{
@Override
public void run()
{
System.out.println("Shutdown hook called!");
}
});
while (true)
{
Thread.sleep(1000);
}
}
}
现在,当您启动程序并使用kill -2 <PID>
将其终止时,将调用关闭挂钩并且您可以正常关闭。
当您使用 BR InterruptedException
从应用程序内部中断线程时,可以捕获interrupt()
(您想要做什么),如以下基本示例所示:< / p>
public class Main
{
public static void main( final String[] args )
{
final Thread t1 = new Thread()
{
@Override
public void run()
{
try
{
while ( true )
{
Thread.sleep( 1000 );
}
}
catch ( final InterruptedException e )
{
System.out.println( "This thread was interrupted!" );
}
}
};
t1.start();
t1.interrupt();
}
}
答案 1 :(得分:2)
InterruptedException
时,会发现 Thread.interrupt()
。它与kill
程序没有任何关系。
答案 2 :(得分:0)
我在我的ubuntu机器上尝试了相同的场景,发现当我们使用kill命令杀死一个进程时,它基本上会杀死整个进程,所以这个行为就像System.exit(1)
,但被中断的异常是不同的东西,其中中断状态标志被设置为告诉线程它已从其他线程接收到中断,还有一件事,如果某个其他线程将通过调用此线程实例上的interrupt()方法来中断此线程,那么您将仅当当前线程处于休眠或等待状态时才获取InterruptedException
。如果线程正在运行,那么在其上调用interrupt()
方法只会将中断标志设置为true(检查中断状态标志,您可以通过此线程实例上的isInterrupted()
方法检查),并且不会抛出InterruptedException
。
参见下面的代码,这里我使用了System.exit(1),在另一个线程中,您将看到整个Java进程已退出,没有中断的异常,原因如上所述。
public static void main(String args[]) {
String importantInfo[] = {
"Mares eat oats",
"Does eat oats",
"Little lambs eat ivy",
"A kid will eat ivy too"
};
try { // my experiment
while(true) {
Thread.sleep(4000);
Thread t = new Thread() {
public void run() {
try {
Thread.sleep(1000);
System.exit(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t.start();
System.out.println(importantInfo[0]);
}
}
catch (InterruptedException ie) {
System.out.println("caught InterruptedException");
}
}
以上修改代码的输出:
Mares吃燕麦
使用退出代码1完成处理