十一、处理线程组中的未控制异常
每种编程语言一个很重要的特性就是其所提供的用来处理程序中错误情况的机制。Java语言和其他的现代语言一样,是提供了异常机制来处理对象程序中的错误。Java提供了很多的类来对应不同的错误。当Java检查到这些错误时,会抛出对应的异常对象。你可以直接使用那些异常类或者实现自己的异常类来处理程序中出项的错误情况。
Java同时提供了捕获和处理异常对象的机制。异常必须被捕获或者重新抛出来。这类异常称为检测异常。还有一类异常不必捕获和处理,称为不检测异常。
在本秘诀中,我们将学习如何捕获线程组中任意线程抛出的不检测异常。
public class Main { public static void main(String[] args) { MyThreadGroup threadGroup = new MyThreadGroup("MyThreadGroup"); Task task = new Task(); for (int i = 0; i < 2; i++) { Thread t = new Thread(threadGroup, task); t.start(); } } } public class MyThreadGroup extends ThreadGroup { public MyThreadGroup(String name) { super(name); } @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(); } } public class Task implements Runnable { @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; } } } }
十二、使用工厂模式创建线程
工厂模式是面向对象语言中使用最多的一个模式。它是一个生产模式,主要用来开发一个对象,这个对象的作用是来生成其他类的对象。当我们想生成其他类的对象时,直接使用工厂对象就好了。我们使用工厂对象的方法来代替 new 操作符。
工厂方法的好处是:
(A):易于改变被生成对象的类,易于改变生产对象的方式
(B):容易控制对象的生产数量
(C):容易统计生成对象的数量
Java提供了 ThreadFactory 接口来方便使用 Thread 对象工厂。一些JDK使用了此接口来生成线程对象。
在本秘诀中,我们教你如何使用 ThreadFactory 接口来创建个性化的线程并同时保存线程创建的统计信息。
public class Main { public static void main(String[] args) { MyThreadFactory factory = new MyThreadFactory("MyThreadFactory"); Task task = new Task(); Thread thread; System.out.printf("Starting the Threads\n"); for (int i = 0; i < 5; i++) { thread = factory.newThread(task); thread.start(); } System.out.printf("Factory stats:\n"); System.out.printf("%s\n", factory.getStats()); } } public class MyThreadFactory implements ThreadFactory { private int counter; private String name; private List<String> stats; public MyThreadFactory(String name) { counter = 0; this.name = name; stats = new ArrayList<String>(); } @Override public Thread newThread(Runnable r) { Thread t = new Thread(r, name+"-Thread_"+counter); counter++; stats.add(String.format("Created thread %d with name %s on " + " %s\n", t.getId(),t.getName(),new Date())); return t; } public String getStats() { StringBuffer buffer = new StringBuffer(); Iterator<String> it = stats.iterator(); while (it.hasNext()) { buffer.append(it.next()); buffer.append("\n"); } return buffer.toString(); } } public class Task implements Runnable { @Override public void run() { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } }
重要:本系列翻译文档也会在本人的微信公众号(此山是我开)第一时间发布,欢迎大家关注。