我想知道在主线程中处理InterruptedException的正确方法是什么。当主线程被中断时?
我看到join()方法抛出InterruptedException,但我想知道如何清理辅助线程以便正常终止。
以下是示例程序:
[main] starting the thread
[main] interrupting the secondary thread
[thread] exiting...
[main] exiting
此代码将打印以下输出:
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread mainThread = Thread.currentThread();
Thread t = new Thread() {
public void run() {
while (true) {
if (Thread.currentThread().isInterrupted()) {
break;
}
}
System.out.println("[thread] interrupting the main thread...");
mainThread.interrupt();
System.out.println("[thread] exiting...");
}
};
System.out.println("[main] starting the thread");
t.start();
System.out.println("[main] interrupting the secondary thread");
t.interrupt();
try {
t.join();
} catch (InterruptedException e) {
System.out.println("[main] InterruptedException indeed happened");
Thread.currentThread().interrupt();
throw e;
}
System.out.println("[main] exiting");
}
}
我发现互联网上的某些文章(例如此http://www.yegor256.com/2015/10/20/interrupted-exception.html)建议将中断标志设置为true并抛出RuntimeException。我不知道这会如何缓解这种情况(在退出之前清理剩余的线程)。
感谢。
编辑:代码剪切我在评论中提到
public void cancelNotification()
{
NotificationCompat.Builder builder = new NotificationCompat.Builder(AcceptUserRequest.this);
builder.setSmallIcon(R.mipmap.lo);
builder.setLargeIcon(BitmapFactory.decodeResource(this.getApplicationContext().getResources(),
R.mipmap.peoplehelperlogo));
builder.setContentTitle("PEOPLE HELPER");
builder.setContentText("Accepted request has been cancelled");
builder.setAutoCancel(true);
Intent intent = new Intent(AcceptUserRequest.this, BroadcastFragment.class); //creates an explicit intent
TaskStackBuilder stackBuilder = TaskStackBuilder.create(AcceptUserRequest.this);
stackBuilder.addParentStack(AcceptUserRequest.this); //adds the intent
stackBuilder.addNextIntent(intent); //put the intent to the top of the stack
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); //(id, flag) //creates a pending intent
builder.setContentIntent(pendingIntent); //adds the PendingIntent to the builder
NotificationManager notificationManager = (NotificationManager) AcceptUserRequest.this.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, builder.build());
}
答案 0 :(得分:1)
在您的示例中,没有任何内容会中断主线程,处理从辅助线程上的调用加入引发的InterruptedException
的代码都不会被执行。所以这并不重要。设置中断标志的目的是让在该线程中执行的其他事情知道中断,这样一切都可以退出它正在做的事情,这不是一个问题。
您可以将main方法包装在try-catch
块中,以记录它捕获的任何内容。要确保记录所有异常,这是正常的做法。
您的代码在辅助线程上调用interrupt
。只要编写该线程以通过清理和退出来响应中断,就不会再做任何事情了。
请勿使用Thread.interrupted()
,请使用Thread.currentThread().isInterrupted()
。 interrupted
方法将中断标志清除为副作用。
捕获InterruptedException
并抛出RuntimeException
与编写java.util.concurrent
类的方式不一致。让InterruptedException
被抛出比将它包装在未经检查的异常中更为惯用。
示例代码不能被信号中断,您必须自己通过编写自己的信号处理程序来实现该功能。