java 板


LINE

大家好,想请教各位前辈一个问题 今天我有一个map Map<String, List<Integer>> map = new HashMap<>(); 有一个function void safeAdd(String key, Integer value), 这个safeAdd方法要做的事情是 map.get(key).add(value) ,这边先不用考虑list 是null 请问要如何做才能达到有效率而且是执行绪安全,以下是我的想法 1. 如果是synchronized safeAdd()这样虽然安全,但是没效率,因为就算不同key 也会要等别的key 完成才能进入 2. 同上,用ConcurrentHashMap一样有这个问题 3. 在safeAdd 里面 先 list A = map.get(key) ,再用synchronized (A) { A.add(value) } ,这是我觉得比较好的作法,但是IntelliJ给我警告说synchronization on local variable,但是get 出来的应该是物件的参考,这样会有问题吗 4. 同上,在方法里面改用 synchronized (map.get(key)) {map.get(key).add(value)} 5. 不考虑用BlockingQueue 或 Vector,因为在safeAdd 里面会有其他对list 的操作,例如用size() 去控制list的长度,我希望这个safeAdd被使用的时候同一时间只有单一执行绪对一个key 里面的list 做操作。 我目前是使用4,我有测试过而且看起来是没问题,但是还是怕有什麽意外因此上来发问,再麻烦各位帮我解答,谢谢。 ----- Sent from JPTT on my iPhone --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 112.104.153.116 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/java/M.1639702666.A.CD7.html
1F:推 jej: 你的Map放在全域变数 要thread safe就有困难 12/17 09:55
2F:→ jej: 如果不能放在block里面 一定要放全域 12/17 09:56
3F:→ jej: 可以考虑用concurrent package下的lock 12/17 09:56
4F:→ jej: 或是使用 synchronized锁定这个Map 12/17 09:56
5F:→ jej: 但如果你有效能考虑 还是建议你重构 看看能不能用singleton 12/17 09:56
6F:→ jej: 把map重构在block里 12/17 09:56
7F:→ jerrychen26: 感谢回答,不过我的问题点比较在於当用synchronized( 12/17 10:05
8F:→ jerrychen26: map.get(key)) 的block期间,可以保证被get出来的这 12/17 10:05
9F:→ jerrychen26: 个list 能达成执行绪安全吗? 12/17 10:05
10F:推 jej: 你这样是锁的东西是什麽就未知了 而且也不一定是单一物件 12/17 11:12
11F:→ jej: 多执行绪还是gg吧 所以才说要不要锁map 12/17 11:12
12F:→ ssccg: ConcurrentHashMap.compute 12/17 13:00
13F:→ ssccg: (key, (k, list) -> { list.add(value); return list }); 12/17 13:02
14F:→ ssccg: 如果需要考虑list为空,就再加个检查和new 12/17 13:03
15F:→ ssccg: 不过compute只会挡update类型的作业,你要达到类似DB交易 12/17 13:16
16F:→ ssccg: (update中也block其他get)的话,就是get也改用compute 12/17 13:16
17F:→ ssccg: 想像你的需求大概是这样 https://ideone.com/tCmTV2 12/17 14:40
18F:→ ssccg: 你的3 4作法其实效果一样,IntelliJ的警告只是个提醒,真正 12/17 14:44
19F:→ ssccg: 的问题在於你synchonized list的期间,如果别的thread做了 12/17 14:45
20F:→ ssccg: Map.put(key, ...),你的list是安全的,但是map.get(key)已 12/17 14:46
21F:→ ssccg: 不再是你的list而是别的东西,所以一楼才建议锁map 12/17 14:47
22F:→ ssccg: 都用compute可以解决这问题 12/17 14:49
23F:→ ssccg: 更正,4的作法有个更糟的点是两个map.get(key)间还有空窗, 12/17 14:54
24F:→ ssccg: 这中间map.put(key,...)的话,呼叫add的list跟上锁的不同 12/17 14:55
25F:→ jerrychen26: 理解了,感谢解答 12/17 15:43
26F:→ darkk6: 做法跟你的 map/list 操作有关,看你是否预期他们会被改变 12/22 01:37
27F:→ darkk6: 会/不会,都有不同适合的写法 12/22 01:37
28F:→ flowwinds: 把key当mutex? 01/08 21:46







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:e-shopping站内搜寻

TOP