多线程学习(六)

线程的捕获异常

由于线程的特性使得不能捕获从现场逃逸的异常,一旦异常逃出run方法,他会向外传播到控制台,除非采取特别的方法来捕获这些异常。

public class ExceptionThread implements Runnable {

	@Override
	public void run() {
		throw new RuntimeException();
	}

	public static void main(String[] args) {
		Executors.newCachedThreadPool().execute(new ExceptionThread());
	}
}

异常传播到控制台:

使用try-catch 来捕获异常:

public class ExceptionThread implements Runnable {

	@Override
	public void run() {
		throw new RuntimeException();
	}

	public static void main(String[] args) {
		try{
			Executors.newCachedThreadPool().execute(new ExceptionThread());
		}catch (Exception e) {
			// TODO: handle exception
			System.out.println("catch the exception:"+e);
		}
	}
}

控制台输出:

证明确实没有捕获到异常 异常传播到控制台了

为了解决这个问题,要修改线程产生的方式。Thread.UncatchExceptionHandler 是java SE5的新的接口,它允许在每个Thread上附着一个异常处理器。现在我们要定制一个ThreadFactory来定制ExecutorService来定制产生的线程的属性(这句话好拗口)

定制的ThreadFactory

public class HandlerThreadFactory implements ThreadFactory {

	@Override
	public Thread newThread(Runnable r) {
		// TODO Auto-generated method stub
		Thread t=new Thread(r);
		t.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
			
			@Override
			public void uncaughtException(Thread t, Throwable e) {
				// TODO Auto-generated method stub
				System.out.println("catch the exception:"+e);
			}
		});
		return t;
	}

}

修改ExceptionThread

public class ExceptionThread implements Runnable {

	@Override
	public void run() {
		throw new RuntimeException();
	}

	public static void main(String[] args) {
		
			Executors.newCachedThreadPool(new HandlerThreadFactory()).execute(new ExceptionThread());
		
	}
}

输出:

通过输出可以看到,异常已经被捕获了。

从上面的定制的ThreadFactory中我们是逐个线程设置异常处理器
如果要在线程中处处设置相同的处理器可以使用 设置默认线程异常处理器的方法:

public class ExceptionThread implements Runnable {

	@Override
	public void run() {
		throw new RuntimeException();
	}

	public static void main(String[] args) {
		//设置线程的默认异常处理器
		Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
			
			@Override
			public void uncaughtException(Thread t, Throwable e) {
				// TODO Auto-generated method stub
				System.out.println("catch the exception:"+e);
			}
		});
			Executors.newCachedThreadPool().execute(new ExceptionThread());
		
	}
}
posted @ 2017-05-07 11:00  风中小蘑菇  阅读(188)  评论(0编辑  收藏  举报