V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
liuxingchina
V2EX  ›  Java

Java 中如何优雅的使用线程池

  •  
  •   liuxingchina · 2019-07-15 10:11:39 +08:00 · 6374 次点击
    这是一个创建于 1991 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题,线程的资料面试题看了一大堆,但是用的很少,大家平时是怎么使用的。上次我是在类里直接写了 static 的 ExecutorService 然后使用的,不知道对不对

    11 条回复    2019-07-19 23:52:26 +08:00
    justRua
        1
    justRua  
       2019-07-15 10:20:49 +08:00
    ExecutorService 里面的构造的线程的队列是无界的,按照阿里手册上的说法是不推荐直接使用,在并发量不大时我是直接用用这个。。。公司项目里是用 spring 配置的线程池 ThreadPoolTaskExecutor,之前公司有用 ExecutorService,在上面包装了一层加了个 Semaphore,线程数量超过最大值时阻塞不让排队。
    xiaoidea
        2
    xiaoidea  
       2019-07-15 10:23:14 +08:00
    没问题。
    建议:1. 不要直接用 Executors 静态方法创建线程池,而是用 ThreadPoolExecutor 的构造方法创建。2. 用 guava 的 MoreExecutors#listeningDecorator 对线程池包装,后续很多 guava 的工具方法可以使用
    lihongjie0209
        3
    lihongjie0209  
       2019-07-15 10:25:48 +08:00
    @justRua 线程池本身就可以配置拒绝策略的, 为什么还要自己使用 Semaphore?
    lihongjie0209
        4
    lihongjie0209  
       2019-07-15 10:26:55 +08:00
    最好是一个 jvm 一个或者两个线程池, 不要在类中实例化, 不然和裸使用线程没区别
    justRua
        5
    justRua  
       2019-07-15 10:30:46 +08:00
    @lihongjie0209 别人写好的,猜他意图应该是任务来了不让排队,也不让拒绝,就阻塞在那等待消费,感觉和 SynchronousQueue 有点类似吧,业务场景是做 ETL,提交的任务必须跑不能丢弃。
    lihongjie0209
        6
    lihongjie0209  
       2019-07-15 10:43:12 +08:00
    @justRua 既然提交的任务不能丢弃, 为什么不用无界队列?

    "线程数量超过最大值时阻塞不让排队。"

    这相当于使用 AQS 实现的 Semaphore 作为一个隐含的队列来用
    airfling
        7
    airfling  
       2019-07-15 11:19:37 +08:00
    我的一般策略是一个应用一个,要么单例,要么全局。
    choice4
        8
    choice4  
       2019-07-15 12:25:34 +08:00 via Android
    现在直接写 CompletableFuture 了。
    Aresxue
        9
    Aresxue  
       2019-07-15 16:26:05 +08:00
    使用 new ThreadPoolExecutor 创建 static 的线程池,线程池要共享的,不然和裸开线程区别不是很大,看情况有必要的话设置为 final 的而且是守护线程。
    SkyLine7
        10
    SkyLine7  
       2019-07-16 16:51:27 +08:00
    自己写一个线程池工具类,包含和核心线程数,最大线程数,阻塞队列,拒绝策略....网上这东西很多的
    qwertyegg
        11
    qwertyegg  
       2019-07-19 23:52:26 +08:00
    forJoinPool?

    ~~~java
    val forkJoinPool = ForkJoinPool(PARALLELISM)
    forkJoinPool.submit{
    some_parallel_stream_job
    }.get()
    ~~~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5504 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 07:17 · PVG 15:17 · LAX 23:17 · JFK 02:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.