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

将任务分配给其他线程处理,使用哪种方式更优

  •  
  •   git00ll · 2021-08-01 13:12:52 +08:00 · 2341 次点击
    这是一个创建于 970 天前的主题,其中的信息可能已经有所发展或是发生改变。

    任务

    一个含有一千万字符串的集合,期望计算每个字符串的 md5 值。并打印出来,不考虑顺序。

    分析

    这是一个 cpu 密集型操作,如果使用单线程做效率不高,在四核机器上准备开启四个线程做

    方案一

    将集合分成四个子集合,每个线程分配一个子集合,for 循环操作

    方案二

    使用 queue 存储字符串,每个线程从 queue 中获取取单个字符串,操作后再读取下一个。

    想要验证的结果

    如果当前有很多 cpu 密集型的小任务,使用多线程时,是每次获取一个(就像线程池读取任务执行那样),还是每次读取一批。哪种更好一点,还是说没有啥差别。

    从线程切换,以及 java 中内存模型,对象引用 角度分析

    补充

    下面这段话是从网上拷贝的,是不是说明方法一一次性传递多个任务到另一个线程更优呢,这样的话这两个线程之间同步的对象应该只有集合本身,而不包含集合内的对象吧???

    JMM 模型下的线程间通信:
    线程间通信必须要经过主内存。
    
    如下,如果线程 A 与线程 B 之间要通信的话,必须要经历下面 2 个步骤:
    
    1 )线程 A 把本地内存 A 中更新过的共享变量刷新到主内存中去。
    
    2 )线程 B 到主内存中去读取线程 A 之前已更新过的共享变量。
    
    
    14 条回复    2021-08-03 20:41:36 +08:00
    MakHoCheung
        1
    MakHoCheung  
       2021-08-01 13:17:48 +08:00
    parallstream 或者自己写 forkjoin,forkjoin 复杂
    chendy
        2
    chendy  
       2021-08-01 13:24:18 +08:00
    parallstream +1
    sagaxu
        3
    sagaxu  
       2021-08-01 13:25:23 +08:00 via Android   ❤️ 1
    先测一下单线程要几秒,不够再优化
    limbo0
        4
    limbo0  
       2021-08-01 13:27:39 +08:00
    像流处理和批处理, 第一种应该更快, 第二种单条处理吞吐注定不会太高
    Building
        5
    Building  
       2021-08-01 13:32:43 +08:00 via iPhone
    每个字符串标记一个 State,每个线程每次取出 State 为等待处理的第一个字符串同时标记为处理中,直到任一线程取不到 State 为等待处理的字符串。
    sagaxu
        6
    sagaxu  
       2021-08-01 13:38:04 +08:00 via Android
    在乎性能就不要用字符串了,你从 bytes 解码成 string 的时间,已经够算出来 md5 了,字符串算一次 hashcode 的时间也够算 md5 了
    v2byy
        7
    v2byy  
       2021-08-01 18:10:54 +08:00 via iPhone
    @Building 直接从一个区间取不行么,就说楼主说的方案一
    wangxn
        8
    wangxn  
       2021-08-01 19:04:20 +08:00
    照理来说,因为 CPU 缓存的存在,方案一应该会有巨大的优势。这种处理方式叫提升 locality 。
    akira
        9
    akira  
       2021-08-01 20:06:58 +08:00
    方案 1,简洁名了。
    jorneyr
        10
    jorneyr  
       2021-08-02 08:22:38 +08:00
    一个字符串应该只有一个 MD5 值,你的这个设计,变成了一个字符串可以有很多不同的 MD5 值。
    rayw0ng
        11
    rayw0ng  
       2021-08-02 09:05:58 +08:00
    两个方案都不实现,一测便知。我猜方案一,毕竟不需要加锁。
    aneostart173
        12
    aneostart173  
       2021-08-02 10:19:22 +08:00
    用 mpi 啊。
    cubecube
        13
    cubecube  
       2021-08-03 10:19:00 +08:00
    瓶颈应该在读取文件 io 和日志。具体得看负载情况,没有定论。
    liian2019
        14
    liian2019  
       2021-08-03 20:41:36 +08:00
    fork join
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5361 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 09:14 · PVG 17:14 · LAX 02:14 · JFK 05:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.