返回信息流在网上看到说都说currenthashmap使用volatile,所以get不用加锁,那么hashtable为啥get要加锁呢,用volatile可以吗
这是一条镜像帖。来源:北邮人论坛 / java / #50268同步于 2016/5/13
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
hashtable里的get为什么要加锁呢
token
2016/5/13镜像同步18 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
【 在 icyfox 的大作中提到: 】
: 历史遗留问题?
我想get如果不加锁,如果在执行到一般时候,被put中断,而这个时候hashmap恰好要rehash,当put执行完后继续get就会出错,得到null,但是这样的话,为啥currenthashmap不加锁呢,或者currenthashmap是怎么处理这个问题的呢
你为什么不考虑考虑hashmap的感受呢..
为啥hashmap不加锁,hashtable要加锁..
这俩有啥区别么?
有,因为hashtable已经废弃了..
【 在 token (stop the world) 的大作中提到: 】
: 我想get如果不加锁,如果在执行到一般时候,被put中断,而这个时候hashmap恰好要rehash,当put执行完后继续get就会出错,得到null,但是这样的话,为啥currenthashmap不加锁呢,或者currenthashmap是怎么处理这个问题的呢
【 在 icyfox 的大作中提到: 】
: 你为什么不考虑考虑hashmap的感受呢..
: 为啥hashmap不加锁,hashtable要加锁..
: 这俩有啥区别么?
: ...................
。。。。hashmap线程不安全啊,
不要用Hashtable。
如果只有一个线程,用HashMap。
如果有多个线程,用ConcurrentSkipListMap或者ConcurrentHashMap。
【 在 nuanyangyang 的大作中提到: 】
: 不要用Hashtable。
: 如果只有一个线程,用HashMap。
: 如果有多个线程,用ConcurrentSkipListMap或者ConcurrentHashMap。
感谢暖洋洋大神,我的意思是hashtable源码中,写数据肯定是要加锁的,但是读数据也是加锁的,读数据加的锁有必要吗?
有必要。如果加锁,那么读和写都必须加锁。
首先,复杂的数据结构读和写都要好多步完成。如果读的过程中出现了写,读会看到不完整的结果,程序会出错。
其次,锁不仅仅保证互斥,还保证顺序。解锁的操作,相当于提供了一个“栅栏”:如果别的线程看到锁已经解了(成功地获得锁),那么必须同样能看到解锁前写入的所有数据。如果不是这样,CPU多个核之间观察到的内存写入顺序可以不同。加锁的操作也是一种栅栏。CPU和编译器都会为了性能,把后面的指令提前执行。如果加锁操作之后的读操作可以被提到加锁之前,就会观察到,“明明程序是先加锁后读取,怎么读到了另外一个线程还没解锁之前写了一半的东西呢?”正确实现的加锁操作会避免上述情况发生。“解锁操作先于这个锁的下一次加锁(happen before)”。要加锁的话,读和写都是要加锁的。
【 在 token 的大作中提到: 】
: 感谢暖洋洋大神,我的意思是hashtable源码中,写数据肯定是要加锁的,但是读数据也是加锁的,读数据加的锁有必要吗?
【 在 nuanyangyang 的大作中提到: 】
: 有必要。如果加锁,那么读和写都必须加锁。
: 首先,复杂的数据结构读和写都要好多步完成。如果读的过程中出现了写,读会看到不完整的结果,程序会出错。
: 其次,锁不仅仅保证互斥,还保证顺序。解锁的操作,相当于提供了一个“栅栏”:如果别的线程看到锁已经解了(成功地获得锁),那么必须同样能看到解锁前写入的所有数据。如果不是这样,CPU多个核之间观察到的内存写入顺序可以不同。加锁的操作也是一种栅栏。CPU和编译器都会为了性能,把后面的指令提前执行。如果加锁操作之后的读操作可以被提到加锁之前,就会观察到,“明明程序是先加锁后读取,怎么读到了另外一个线程还没解锁之前写了一半的东西呢?”正确实现的加锁操作会避免上述情况发生。“解锁操作先于这个锁的下一次加锁(happen before)”。要加锁的话,读和写都是要加锁的。
: ...................
6666