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线程的启动以结束,但是我们要注意的是当池内消耗完之后的等待和同步问题,假设在测试期间并发测试很小的情况下,无法出现线程池内线程耗尽的情况,当某些糟糕的代码导致线程一直在使用的情况,就造成任务无法被及时处理甚至不处理。建议在测试阶段不要创建太大的池,方便及时发现代码漏洞。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java ExecutorServiceJava 并发包中的一个接口,它提供了一种简化多线程编程的方式。它实际上是一个线程池的封装,可以帮助我们管理和控制执行多个任务的线程。 使用 ExecutorService 可以将任务提交给线程池,在线程池中由线程执行任务,而不需要手动创建线程。这种方式可以充分利用现有线程,并且可以根据需要灵活地调整线程的数量,避免了频繁创建和销毁线程的开销,提高了程序的性能和效率。 我们可以通过创建 ExecutorService 对象来使用线程池。一般来说,常用的线程池实现类有 ThreadPoolExecutor、FixedThreadPool、ScheduledThreadPool 等。 使用 ExecutorService 的步骤如下: 1. 创建 ExecutorService 对象,可以通过 Executors 工厂类中的静态方法来创建。 2. 创建任务(Runnable 或 Callable),将任务提交给 ExecutorService。 3. ExecutorService 会根据具体的线程池实现类来管理线程,并分配线程来执行任务。 4. 执行完任务后,可以通过调用 shutdown() 方法来关闭线程池。 ExecutorService 提供了一系列的方法来管理和控制线程池,如 submit() 方法可以提交任务并返回一个 Future 对象,通过 Future 对象可以获取任务的执行结果;invokeAll() 方法可以同时提交多个任务并等待它们全部完成;shutdown() 方法可以平缓地关闭线程池,等待已提交的任务执行完再关闭线程池。 需要注意的是,使用 ExecutorService 时应注意线程安全问题,如共享变量的同步访问等。此,对于耗时较长的任务应使用异步的方式提交。 总之,ExecutorService使用可以简化多线程编程,提高程序效率,但需要根据具体情况选择合适的线程池实现类和合理配置线程池参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值