关于 Java 线程池的一些疑问 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
nl101531
V2EX    Java

关于 Java 线程池的一些疑问

  •  1
     
  •   nl101531
    mrdear 2018 年 8 月 8 日 4623 次点击
    这是一个创建于 2818 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在《 Java 并发编程艺术》书中有这样一段话

    多线程竞争锁时会引起上下文切换,多余多核处理数据时可以将数据的 ID 按照 Hash 算法取模分段,不同的线程处理不同段的数据。

    关于这个我以线程池为例,可以理解为使用一个大的线程池不如使用多个小的线程池,将任务通过 hash 算法分散到不同的线程池中,线程池的 Channel 是阻塞队列实现,高并发抢任务会造成线程阻塞,导致上下文切换,因此这种分散的方法降低单个线程池抢任务的并发量。

    这样理解有问题吗?这种做法目前没怎么见过,是真的有效果吗?

    第 1 条附言    2018 年 8 月 8 日
    写了测试,假设 qps1000,30 个线程能够保证每个处理在 15ms 以内。

    分成 3 个线程池,每个之中有 10 个线程,那么处理会相当慢,竞争很激烈。因此结论不正确。
    18 条回复    2018-11-07 17:36:23 +08:00
    vela
        1
    vela  
       2018 年 8 月 8 日
    如果任务的耗时方差比较大,有个别耗时较长,可能会造成部分线程池饥饿。
    简单就这样的代码,但是更多是为了解决按照特定数据进行串行化的……
    Map<Integer, Executor> executorPool;
    void init() {
    executorPool = IntStream.range(0, 10).boxed().collect(collectingAndThen(toMap(identity(), it -> Executors.newXxxx(..))), Collections::unmodifiableMap);
    }

    void foo(SomePojo pojo) {
    executorPool.get(pojo.getSomeField().hashCode() % executorPool.size()).execute(() -> {
    // do something...
    });
    }
    ooToo
        2
    ooToo  
       2018 年 8 月 8 日 via iPhone
    有问题,竞争锁的是线程和线程,不是线程池和池,而且需要同步的才需要竞争锁。CPU 核心就那么多
    nl101531
        3
    nl101531  
    OP
       2018 年 8 月 8 日
    @ooToo 在一个大的线程池里面是那么多线程竞争一个阻塞队列上的锁,而分散开来的话就有了多个锁,每个线程池锁竞争的锁对象是不一样的了。
    szq8014
        4
    szq8014  
       2018 年 8 月 8 日   2
    多个小的线程池不还是用锁来同步吗?这句话的重点应该是 “多线程竞争 [锁] 时会引起上下文切换”,所以最好还是不要把数据上锁,不上锁就需要提前把数据分给每个线程,每个线程一亩三分地自己搞自己的。
    hash 取模后不就做到每个线程不需要锁就可以保证数据安全了么~
    nl101531
        5
    nl101531  
    OP
       2018 年 8 月 8 日
    @szq8014 大佬这分析有道理,貌似是我理解有问题,作者原意应该只是表达可以用这种做法实现无锁。
    D3EP
        6
    D3EP  
       2018 年 8 月 8 日
    @boywang004 偶见天舟 哈哈
    sagaxu
        7
    sagaxu  
       2018 年 8 月 8 日 via Android
    如果多个小线程池优于单个大线程池,线程池内部实现的时候做个分段不就好了?
    ioth
        8
    ioth  
       2018 年 8 月 8 日
    java 还有效率?指针都不敢有。线程什么的,交给 c 和 c++ 吧。
    yidinghe
        9
    yidinghe  
       2018 年 8 月 8 日 via Android
    总的来说,有锁在那里,你怎么摆弄线程池没什么区别的
    WildCat
        10
    WildCat  
       2018 年 8 月 8 日
    @ioth 惊了。
    iFlicker
        11
    iFlicker  
       2018 年 8 月 8 日
    @ioth 钓鱼么。。。
    AllenTsui
        12
    AllenTsui  
       2018 年 8 月 8 日
    @ioth PHP 全宇宙第一 <(* ̄ ̄)~
    ioth
        13
    ioth  
       2018 年 8 月 9 日
    @AllenTsui 没错,就是一堆$看了脑袋大,是除了 vb 之外 sb 第 2 的语言。
    ioth
        14
    ioth  
       2018 年 8 月 9 日
    @WildCat 本来就是做个小电器的接口语言设计,能不垃圾么?还讲 java 的艺术,那 foxpro 还讲优雅?
    所以后来安卓这种山寨货也就用 java 了。
    vela
        15
    vela  
       2018 年 8 月 9 日
    @D3EP =__=,我难道应该再换个 id 才能不被认出来么。
    wocanmei
        16
    wocanmei  
       2018 年 8 月 21 日   1
    没有看过 Java 并发编程艺术,但看起来这里说的应该是锁分段而不是线程池,比如

    ```java
    public void synchronizeOneLock(int uid) {
    synchronized (this) {

    // ...
    }
    }

    private final Object[] locks;

    public void synchronizeMultiLock(int uid) {
    synchronized (locks[uid % locks.length]) {

    // ...
    }
    }
    ```

    假设用户可以用 uid 表示,synchronizeOneLock 会将所有用户在 this 这一个锁上同步,而 synchronizeMultiLock 则会根据 uid 散列到多个锁上,不同的数据在不同的锁上进行同步,避免了不必要的锁竞争
    nl101531
        17
    nl101531  
    OP
       2018 年 8 月 21 日
    @wocanmei 感谢,是应该这样理解
    409474917
        18
    409474917  
       2018 年 11 月 7 日
    @ioth 你这个喷子呀,有本事不要用淘宝,淘宝 86%的系统后台都是 java 写的,你也不要用安卓手机,你的家人也不要用安卓手机。看你的这些发言,实际中你应该是个没房没车的丝,每个月拿着几千块钱的工资。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2382 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 54ms UTC 01:01 PVG 09:01 LAX 18:01 JFK 21:01
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86