共享变量HashMap,put值时加synchronized,读取不加锁,读取能保证读取到最新的值吗?
共享变量HashMap,put值时加synchronized,读取不加锁,读取能保证读取到最新的值吗?
如果map的value不是线程安全的, 是有可能读到旧值的.
因为线程是从主内存中读取值, 而最新的值是存在CPU高速缓存中的; 相关关键词就是volatile, 如果属性被volatile修饰, 那么每次读取值都会从CPU缓存中读取新值刷新到主内存
如果存在并发问题,建议将 HashMap 换成 ConcurrentHashMap,它是线程安全的。
另外,当 synchronized 代码块执行完成后了,更新的值是会立即刷新到主内存的,在根据缓存一致性协议,get 的时候会拿到新值,只是存在短暂延迟,因为不能保证更新的值立即对其他线程可见。为了保险起见,换成 ConcurrentHashMap 最好,因为它内部保存数据的 table 数组是使用 volatile 修饰了的,可保证在数据更新后,可以立即获取到新值。如下:
transient volatile Node<K,V>[] table;
8 回答2.5k 阅读
2 回答5k 阅读✓ 已解决
5 回答805 阅读
4 回答1.1k 阅读✓ 已解决
4 回答1.1k 阅读✓ 已解决
3 回答2.1k 阅读
1 回答2.5k 阅读✓ 已解决
put加锁可以保证写入不会出错。读取不用synchronized,但是cpu一般都支持缓存一致性协议,你可以理解为很短的时间后,其他线程就能拿到最新值。但的确存在延迟(我不知道这个延迟是多少,但是肯定比毫秒还低),如果恰巧在这个时间段读,确实会读到旧数据。