【多线程】线程池吃掉异常 submit

测试代码

public class MyTest {

    public static void main(String[] args) throws InterruptedException {
        System.out.println("=============start");
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(1, 10, 0, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
        for (int i = 0; i <= 6; i++) {
            MyTask myTask = new MyTask(i);
            threadPool.submit(myTask);
            Thread.sleep(300L);
        }
        System.out.println("=============end");
    }

}

class MyTask implements Runnable {
    private int i = 0;

    public MyTask(int i) {
        this.i = i;
    }

    @Override
    public void run() {
        if (i == 3 || i == 6) {
            throw new RuntimeException("i=" + i + "异常");
        }
        System.out.println(i);
    }
}

执行结果

=============start
0
1
2
4
5
=============end

原因(FutureTask源码)

 public void run() {
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return;
        try {
            Callable<V> c = callable;
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    result = c.call();
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    //--------------原因---------------将Exception设置到结果
                    setException(ex);
                }
                if (ran)
                    set(result);
            }
        } finally {
            runner = null;
            int s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
    }

    protected void setException(Throwable t) {
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
            outcome = t;
            UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state
            finishCompletion();
        }
    }

解决方法

1、捕获future.get()异常--->处理
2、submit改用execute()执行

原文地址:https://www.cnblogs.com/itplay/p/12660826.html