从哪里发现默认行为?每个线程都属于一个由 java.lang.ThreadGroup 类表示的线程组。顾名思义,线程组答应您将线程组合在一起。您可能是为了方便而将线程组合,例如,一个线程池中的所有线程都属于组 X,而另一个池的所有线程则属于组 Y,或者是为了访问控制而将线程进行组合。组 X 中的线程无权访问或改变组 Y 中的线程,除非它们都在同一线程组内(或在一个子组内)。
public class WindowDump { public static void main(String args[]) throws Exception { ThreadGroup group = new LoggingThreadGroup("Logger"); new Thread(group, "myThread") { public void run() { System.out.println(1 / 0); } }.start(); } }
private Filter makeFilter(String name) { Filter f = null; try { Class c = Class.forName(name); f = (Filter)c.newInstance(); } catch (Exception e) { if (name != null) { System.err.println("Unable to load filter: " + name); } } return f; }
private Formatter makeFormatter(String name) { Formatter f = null; try { Class c = Class.forName(name); f = (Formatter)c.newInstance(); } catch (Exception e) { f = new SimpleFormatter(); } return f; }
// Overridden abstract Handler methods
public void close() { }
public void flush() { }
/** * If record is loggable, format it and add it to window */ public void publish(LogRecord record) { String message = null; if (isLoggable(record)) { try { message = getFormatter().format(record); } catch (Exception e) { reportError(null, e, ErrorManager.FORMAT_FAILURE); return; } try { window.addLogInfo(message); } catch (Exception e) { reportError(null, e, ErrorManager.WRITE_FAILURE); } } } }
清单 6. LoggingWindow 的定义
import java.awt.*; import javax.swing.*;
public class LoggingWindow extends JFrame { private JTextArea textArea;
public LoggingWindow(String title, final int width, final int height) { super(title); EventQueue.invokeLater(new Runnable() { public void run() { setSize(width, height); textArea = new JTextArea(); JScrollPane pane = new JScrollPane(textArea); textArea.setEditable(false); getContentPane().add(pane); setVisible(true); } }); }
public void addLogInfo(final String data) { EventQueue.invokeLater(new Runnable() { public void run() { textArea.append(data); } }); } }