• 并发时捕获异常


    由于线程的本质,使你不能捕获从线程中逃逸的异常。一旦异常逃逸出run()方法,就会传播到控制台,除非采取特殊的步骤。

    public class ExceptionThread implements Runnable {
    public void run() {
    throw new RuntimeException();
    }
    public static void main(String[] args) {
    ExecutorService exec = Executors.newCachedThreadPool();
    exec.execute(new ExceptionThread());
    System.out.println("ccccccc");
    }
    } ///:~

    输出:

    ccccccc
    Exception in thread "pool-1-thread-1" java.lang.RuntimeException
    at ExceptionThread.run(ExceptionThread.java:7)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

    main线程不能捕捉到。

    即使放到main的try catch也没作用:

    public class NaiveExceptionHandling {
    public static void main(String[] args) {
    try {
    ExecutorService exec =
    Executors.newCachedThreadPool();
    exec.execute(new ExceptionThread());
    System.out.println("xxxxxxxxxxx");
    } catch(RuntimeException ue) {
    // This statement will NOT execute!
    System.out.println("Exception has been handled!");
    }
    }

    输出:

    Exception in thread "pool-1-thread-1" java.lang.RuntimeException
    at ExceptionThread.run(ExceptionThread.java:7)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

    为了解决这个问题,需要修改Executors产生线程的方式。

    import java.util.concurrent.*;

    class ExceptionThread2 implements Runnable {
    public void run() {
    Thread t = Thread.currentThread();
    System.out.println("run() by " + t);
    System.out.println(
    "eh = " + t.getUncaughtExceptionHandler());
    throw new RuntimeException();
    }
    }

    class MyUncaughtExceptionHandler implements
    Thread.UncaughtExceptionHandler {
    public void uncaughtException(Thread t, Throwable e) {
    System.out.println("caught " + e);
    }
    }

    class HandlerThreadFactory implements ThreadFactory {
    public Thread newThread(Runnable r) {
    System.out.println(this + " creating new Thread");
    Thread t = new Thread(r);
    System.out.println("created " + t);
    t.setUncaughtExceptionHandler(
    new MyUncaughtExceptionHandler());
    System.out.println(
    "eh = " + t.getUncaughtExceptionHandler());
    return t;
    }
    }

    public class CaptureUncaughtException {
    public static void main(String[] args) {
    ExecutorService exec = Executors.newCachedThreadPool(
    new HandlerThreadFactory());
    exec.execute(new ExceptionThread2());
    }
    } /* Output: (90% match)
    HandlerThreadFactory@de6ced creating new Thread
    created Thread[Thread-0,5,main]
    eh = MyUncaughtExceptionHandler@1fb8ee3
    run() by Thread[Thread-0,5,main]
    eh = MyUncaughtExceptionHandler@1fb8ee3
    caught java.lang.RuntimeException
    *///:~

  • 相关阅读:
    [hibernate]org.hibernate.PropertyAccessException: Null value was assigned to a property of primitive type setter
    [extjs] extjs 5.1 API 开发 文档
    [java] Unsupported major.minor version 51.0 错误解决方案
    [kfaka] Apache Kafka:下一代分布式消息系统
    [spring] org.objectweb.asm.ClassVisitor.visit(IILjava/lang/String;Ljav 解决
    [spring] 对实体 "characterEncoding" 的引用必须以 ';' 分隔符结尾
    [java] java 中Unsafe类学习
    [java] java 线程join方法详解
    [java] jstack 查看死锁问题
    ORACLE DG之参数详解
  • 原文地址:https://www.cnblogs.com/daxiong225/p/8974387.html
Copyright © 2020-2023  润新知