• 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    
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    python的多进程
    sqlalchemy的缓存和刷新
    uuid
    区块链的理解
    列表推导式,两个for循环的例子
    Fiddler 抓包工具总结
    python---webbrowser模块的使用,用非系统默认浏览器打开
    使用jmeter做web接口测试
    selenium2中关于Python的常用函数
    Selenium2+Python自动化学习笔记(第1天)
  • 原文地址:https://www.cnblogs.com/zhaiqianfeng/p/4620135.html
Copyright © 2020-2023  润新知