Code Bye

关于线程池 ExecutorService 的一个疑问

 

场景:有一个服务器端方法,会被并发调用到。该方法内部会创建 2 个线程去处理业务。因此每一次对该方法的调用都会创建两个新线程,我希望能将这产生的大量线程用线程池来管理,于是使用了 ExecutorService,代码如下。
问题:因为在方法中,我用了 shutdown() 方法,且线程池对象又是 static,所以当第二个请求(也就是对方法的第二次调用)过来时,就报出了RejectedExecutionException异常。但如果不设为static,那岂不是每次请求(调用)都会新建一个线程池,且每个线程池只有 2 个线程,这样线程池有什么意义呢? 还是我对于线程池的用法有误?? 请指教,谢谢!

public class ThreadPoolTest {

    // 创建一个static的线程池(我理解为线程池本身是可以只实例化一次,里面的内容(线程)是可变的,不知对不对?)
    private static ExecutorService executor = Executors.newCachedThreadPool();

    // 该方法为业务处理方法,会被并发调用
    public static process() {
        Thread1 th1 = new Thread1(); // 创建一个自定义线程
        executor.execute(th1);

        Thread1 th2 = new Thread2(); // 创建一个自定义线程
        executor.execute(th2);

        // 关闭线程池。问题就在这儿,这个线程池是只实例化一次的,但既然已经关闭了,那么当下一批请求过来的时候,
        // 就会有RejectedExecutionException报出。但如果不关闭线程池,则程序是无法继续执行下去的。
        // 再如果线程池executor不设计成static,当前class也不设计为单例,那每次请求本process()方法时
        // 均创建一个只有thread1、thread2两个线程的线程池,那“池”的意义也就失去了。
        executor.shutdown();

        // 继续下面的逻辑......
    }
}

5分
既然这样楼主 为何不用      单例模式  自己写个获取单例模式的方法撒
楼主为什么要关闭线程池。。启动服务之后不应该一直等待接收处理任务么
引用 2 楼 u012171905 的回复:

楼主为什么要关闭线程池。。启动服务之后不应该一直等待接收处理任务么

对,我本来也这么想。但测试了一下,发现如果不关闭,那程序就一直停在线程执行上,无法继续执行。


20分
引用 3 楼 I_am_a_java_CaiNiao 的回复:
Quote: 引用 2 楼 u012171905 的回复:

楼主为什么要关闭线程池。。启动服务之后不应该一直等待接收处理任务么

对,我本来也这么想。但测试了一下,发现如果不关闭,那程序就一直停在线程执行上,无法继续执行。

你提交给线程池执行的任务是一直进行的?不会结束吗?


15分
所谓线程池不是你线程跑完了就关闭了
是为了减少创建新线程而导致的性能开销
说白了就是重复利用线程
如果你的线程是非外部条件而永远不结束的,那么就没必要用线程池了
一般来说,线程池是不需要shutdown的
另外一个ExecutorService?的execute方法传入的是Runnable,不是已经创建好的Thread
引用 4 楼 u012171905 的回复:
Quote: 引用 3 楼 I_am_a_java_CaiNiao 的回复:
Quote: 引用 2 楼 u012171905 的回复:

楼主为什么要关闭线程池。。启动服务之后不应该一直等待接收处理任务么

对,我本来也这么想。但测试了一下,发现如果不关闭,那程序就一直停在线程执行上,无法继续执行。

你提交给线程池执行的任务是一直进行的?不会结束吗?

会结束的。现在我已经搞清楚了,之前是一直遇到分线程还没执行完,主线程就继续往下了,导致分线程还没有返回值,所以当时用了一个 executorService.awaittermination() 方法,这个方法需要与 shutDown() 方法结合使用。现在我发现我思路错了,已经换成 Callable 与 FutureTask 结合使用了。线程池也不再去关闭了。
问题已解决。
谢谢解答!

引用 5 楼 wangxf_8341 的回复:

所谓线程池不是你线程跑完了就关闭了
是为了减少创建新线程而导致的性能开销
说白了就是重复利用线程
如果你的线程是非外部条件而永远不结束的,那么就没必要用线程池了
一般来说,线程池是不需要shutdown的
另外一个ExecutorService?的execute方法传入的是Runnable,不是已经创建好的Thread

已懂,谢谢!


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明关于线程池 ExecutorService 的一个疑问