zoukankan      html  css  js  c++  java
  • 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    
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    修改注册表启动项
    修改IP和DNS的dos命令
    屏蔽windows快捷键的方法
    本地IP,掩码,网关,DNS设置
    DevExpress的提示框
    ASP.NET如何批量保存动态生成的文本框?
    [转]SQL Server 安全性概論與無法刪除資料庫使用者的解決辦法
    如何用C#对Gridview的项目进行汇总统计?
    如何用javasript对Gridview的项目进行汇总统计?
    [转]C#如何获取客户端IP地址
  • 原文地址:https://www.cnblogs.com/zhaiqianfeng/p/4620135.html
Copyright © 2011-2022 走看看