Java ExecutorService使用要小心

公司的项目中使用了ExecutorService java中的线程池进行管理线程,使用submit进行线程申请线程时出现线程内抛出NullPointException被捕捉,导致调试难度急剧加大,原因是ExecutorService自行捕捉了异常,解决方法:

Future result = Executors.newCachedThreadPool().submit();

        try {

            result.get();

        } catch (InterruptedException e) {

            e.printStackTrace();

        } catch (ExecutionException e) {

            throw new RuntimeException(e);

        }

在这个地方将异常重新抛出。

这种方法虽然可以解决以上的问题,但get()是一个阻塞的方法,会一直等待结果。

Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {

            @Override

            public void uncaughtException(Thread t, Throwable e) {

                System.out.print("++++++++++++++++++++++");

//                e.printStackTrace();

            }

        });

        ExecutorService executorService = Executors.newCachedThreadPool(new ThreadFactory() {

            @Override

            public Thread newThread(Runnable r) {

                Thread t = new Thread(r);

                return t;

            }

        });


      for (int i = 0; i < 10; i++) {

    //这个地方如果使用sumbit则捕捉不到相关异常。

            executorService.execute(new Runnable() {

                @Override

                public void run() {

                    // TODO: 2018/1/16 0016 线程任务

                }

            });

        }

ExecutorService是java提供的线程管理工具,我们可以使用Executors来创建一个线程池,这样我们就不需要在使用线程的地方去new thread的了,现在java中创建线程池的方式有一下几种:

1.Executors.newCacheThreadPool();

CacheThreadBool会为每一个任务创造线程,会在程序执行过程中创建与所需线程相等的线程数,并在回收旧线程时停止创建旧线程。

2.Executors.newFixedThreadPool(size);

FixedThreadPool指定线程数量,在线程均被占用后排队等待空闲线程。

3.Executors.newSingleThreadExecutor();

相当于size = 1的FixedThreadPool,使用于独占式的操作,比如操作摄像头等硬件设备,不允许多线程同时占用。

使用线程池我们不需要care线程的启动以结束,但是我们要注意的是当池内消耗完之后的等待和同步问题,假设在测试期间并发测试很小的情况下,无法出现线程池内线程耗尽的情况,当某些糟糕的代码导致线程一直在使用的情况,就造成任务无法被及时处理甚至不处理。建议在测试阶段不要创建太大的池,方便及时发现代码漏洞。

你可能感兴趣的:(Java ExecutorService使用要小心)