zoukankan      html  css  js  c++  java
  • 【多线程】线程池吃掉异常 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()执行

  • 相关阅读:
    java访问mysql方法数据库
    iOS8:把这些七招APP哭
    String、StringBuffer与StringBuilder差分
    陈词滥调,正确使用memset
    spring Annotation 组分注塑
    类是公共,它应该被命名为.java文件声明
    【UVA】10012
    Android在ListView显示图片(重复混乱闪烁问题)
    oc-15-枚举结构体
    oc-15-self
  • 原文地址:https://www.cnblogs.com/itplay/p/12660826.html
Copyright © 2011-2022 走看看