• Java并发之线程异常捕获


    由于线程的本质特性,使得你不能捕获从线程中逃逸的异常,如:

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class App {
    
    	public static void main(String[] args) throws InterruptedException {
    		try {
    			ExecutorService exec = Executors.newCachedThreadPool();
    			exec.execute(new Task());
    			exec.shutdown();
    		} catch (Exception e) {
    			System.out.println("异常:"+e.getMessage());
    		}
    	}
    }
    
    /**
     * 定义任务
     * 
     * @author Administrator
     */
    class Task implements Runnable {
    
    	@Override
    	public void run() {		
    		throw new RuntimeException("运行时错误");
    	}
    }

    输出:

    Exception in thread "pool-1-thread-1" java.lang.RuntimeException: 运行时错误
    at Task.run(App.java:27)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)

    可以看到一旦异常逃逸出run方法,将直接传播到顶层,且捕获不了。当然你可以在run方法里处理这些异常,但如果不想再run里处理呢?

    为了解决这个问题,我们需要修改Executors产生线程的方式,Thread.setUncaughtExceptionHandler是Java5的新接口,它允许你在每个Thread对象上附着一个异常处理器。Thread.setUncaughtExceptionHandler.uncaughtException()会在线程因未捕获的异常而临近死亡时被调用。这里仍然需要用到线程工厂ThreadFactory:

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ThreadFactory;
    
    public class App {
    
    	public static void main(String[] args) throws InterruptedException {
    		ExecutorService exec = Executors.newCachedThreadPool(new MyThreadFactory());
    		exec.execute(new Task());
    		exec.shutdown();
    	}
    }
    
    /**
     * 定义任务
     * 
     * @author Administrator
     */
    class Task implements Runnable {
    
    	@Override
    	public void run() {		
    		throw new RuntimeException("运行时错误");
    	}
    }
    
    /**
     * 线程工厂
     * @author Administrator
     *
     */
    class MyThreadFactory implements ThreadFactory{
    
    	@Override
    	public Thread newThread(Runnable r) {
    		Thread t=new Thread(r);
    		t.setUncaughtExceptionHandler(new MysetUncaughtExceptionHandler());
    		return t;
    	}
    }
    
    /**
     * 异常处理器
     * @author Administrator
     *
     */
    class MysetUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{
    
    	@Override
    	public void uncaughtException(Thread t, Throwable e) {
    		System.out.println("异常:"+e.getMessage());
    	}
    }

    输出:

    异常:运行时错误

    其实在实际应用中根据定制,ThreadFactory是经常用到的。

    出处:http://www.zhaiqianfeng.com    
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    [nodejs]npm国内npm安装nodejs modules终极解决方案
    [nodejs]解决mysql和连接池(pool)自动断开问题
    [nodejs]国内npm安装nodejs modules失败的几个解决方案
    [less]用webstorm自动编译less产出css和sourcemap
    [javascript] Promise API
    [javascript]巧用sourcemap快速定位javascript中的问题
    Gruntjs提高生产力(四)
    Gruntjs提高生产力(三)
    Gruntjs提高生产力(二)
    Gruntjs提高生产力(一)
  • 原文地址:https://www.cnblogs.com/zhaiqianfeng/p/4620135.html
Copyright © 2020-2023  润新知