声明:本文是《 Java 7 Concurrency Cookbook 》的第一章, 作者: Javier Fernández González 译者:郑玉婷
处理线程组内不受控制异常
对于编程语言来说,一个非常重要的事情是提供管理应用出错情况的机制。Java 语言, 作为最现代的编程语言,实现except基于异常的机制来管理出错情况,它提供很多种类来表示不同的错误。当检测到一个异常状况时,这些异常会被Java类们抛出。你也可以使用这些异常, 或者实现你自己的异常, 来管理你的类产生的错误。
Java 也提供机制来捕捉和处理这些异常 。有些一定要被捕捉或者使用方法的throws句组再抛出,这些异常称为检查异常(checked exceptions)。有些异常不需要被捕捉,这些称为未检查异常(unchecked exceptions)。
在这个指南中,你将学习了如何使用通用方法来处理线程对象抛出的所有未捕获的异常。
另一种可能是创建一个方法,捕获所有被ThreadGroup类的任何线程抛出的非捕捉异常。
在这个指南中, 我们将用例子来学习如何设置处理程序。
准备
指南中的例子是使用Eclipse IDE 来实现的。如果你使用Eclipse 或者其他的IDE,例如NetBeans, 打开并创建一个新的java项目。
怎么做呢…
按照这些步骤来实现下面的例子::
1. 首先, 创建一个类叫MyThreadGroup来扩展 ThreadGroup 类 。我们必须声明一个拥有一个参数的构造方法,因为ThreadGroup类有一个没有参数的构造方法。
public class MyThreadGroup extends ThreadGroup { public MyThreadGroup(String name) { super(name); }
2. 覆盖 uncaughtException() 方法。ThreadGroup 类的其中一个线程抛出异常时,就会调用此方法 。在这里,这个方法会把异常和抛出它的线程的信息写入操控台并中断ThreadGroup类的其余线程。
@Override public void uncaughtException(Thread t, Throwable e) { System.out.printf("The thread %s has thrown an Exception/n",t.getId()); e.printStackTrace(System.out); System.out.printf("Terminating the rest of the Threads/n"); interrupt(); }
3. 创建一个类,名为 Task, 并一定要实现Runnable 接口。
public class Task implements Runnable {
4. 实现run()方法。在这里,我们将会抛出一个 AritmethicException 异常。这样,我们要用1000除以一个随机数字,直到随机生成的数为0的时候,异常就会被抛出。
@Override public void run() { int result; Random random=new Random(Thread.currentThread().getId()); while (true) { result=1000/((int)(random.nextDouble()*1000)); System.out.printf("%s : f/n",Thread.currentThread().getId(),result); if (Thread.currentThread().isInterrupted()) { System.out.printf("%d : Interrupted/n",Thread.currentThread().getId()); return; } } }
5. 现在,我们来实现例子的主类通过实现一个Main类和实现一个main() 方法.
public class Main { public static void main(String[] args) {
6. 创建一个 MyThreadGroup 类对象。
MyThreadGroup threadGroup=new MyThreadGroup("MyThreadGroup");
7. 创建一个 Task 类对象.
Task task=new Task();
8. 创建 2个 Thread 对象与这个 Task 并开始他们。
for (int i=0; i<2; i++){ Thread t=new Thread(threadGroup,task); t.start(); }
9. 运行例子并查看结果。
它是怎么工作的…
当运行这个例子,你会发现线程对象是如何抛出异常和其他被中断的。当一个非捕捉异常在线程内抛出,JVM会为这个异常寻找3种可能handlers。
首先, 它寻找这个未捕捉的线程对象的异常handle,如在线程中处理不受控制异常中介绍的,如果这个handle 不存在,那么JVM会在线程对象的ThreadGroup里寻找非捕捉异常的handler,如我们在这个指南中学习的。如果此方法不存在,那么 JVM 会寻找默认非捕捉异常handle。如果没有 handlers存在, 那么 JVM会把异常的 stack trace 写入控制台并结束任务。
参见
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/140947.html