采纳答案成功!
向帮助你的同学说点啥吧!感谢那些助人为乐的人
老师我有疑问,信号量用newFixedThreadPool代替是不是也可以,如果我设置线程数5,那么一次也就只能生成5个线程去执行,多的任务就会放到队列中等待。
信号量能不能被 FixedThreadPool 代替呢?这个问题相当于,信号量是可以限制同时访问的线程数,那为什么不直接用固定数量线程池去限制呢?这样不是更方便吗?比如说线程池里面有 3 个线程,那自然最多只有 3 个线程去访问了。
这是一个很好的问题,我们在实际业务中会遇到这样的情况:假如,在调用慢服务之前需要有个判断条件,比如只想在每天的零点附近去访问这个慢服务时受到最大线程数的限制(比如 3 个线程),而在除了每天零点附近的其他大部分时间,我们是希望让更多的线程去访问的。所以在这种情况下就应该把线程池的线程数量设置为 50 ,甚至更多,然后在执行之前加一个 if 判断,如果符合时间限制了(比如零点附近),再用信号量去额外限制,这样做是比较合理的。
再说一个例子,比如说在大型应用程序中会有不同类型的任务,它们也是通过不同的线程池来调用慢服务的。因为调用方不只是一处,可能是 Tomcat 服务器或者网关,我们就不应该限制,或者说也无法做到限制它们的线程池的大小。但可以做的是,在执行任务之前用信号量去限制一下同时访问的数量,因为我们的信号量具有跨线程、跨线程池的特性,所以即便这些请求来自于不同的线程池,我们也可以限制它们的访问。如果用 FixedThreadPool 去限制,那就做不到跨线程池限制了,这样的话会让功能大大削弱。
基于以上的理由,如果想要限制并发访问的线程数,用信号量是更合适的。
感谢提问者所提问题和老师解答,要不我就不能深刻理解semaphore和threadpool的各自作用和使用场景了。 对于第二个例子我理解了,但是第一个有些不理解(实际业务小白,问的是基于理论理解不明白之处,很多实际情况可能考虑不到,还望老师多包涵): 第二个例子里,假设8个不同的caller,在任意时刻只有5个caller(与5个semaphore一一对应)能被执行,这种情况下确实无法使用thread pool去控制慢服务的被调用; 第一个例子里推荐使用semaphore,是因为如果在零点附近的时间段内使用thread pool方式去访问的话,会很耗资源,还可能在特殊时间段内没满足只容许3个threads访问的假设要求(if等大线程池完全执行完毕,有可能会等超过这个特殊时间段,还可能刚关就要打开了),是要先terminate之前有50个线程的thread pool,然后开启3个线程的thread pool,等过了这个特殊时间段,再关闭小线程池再打开大线程池?如果不是这个原因,还请老师解惑?
不好意思,下节课从正确的角度讲了我的这个问题。我的问题是从不被推荐的角度(反面角度),如果对这个反面角度的理解并没有什么用,老师就不用回答了。
非常感谢!
登录后可查看更多问答,登录/注册
JUC全方位讲解,构建并发工具类知识体系
963 11
1.4k 10
995 10
977 10
1.4k 9