搜索内容

有一个问题?

如果您有任何疑问,可以在下面询问或输入您要寻找的!

请教一下关于 SynchronizedList以及ConcurrentHashMap锁的问题

Java 未结 2 782
MakeFunny
MakeFunny 2021-03-08 17:12

想请教一下为什么 SynchronizedList 是读写均加锁,而 ConcurrentHashMap 只有写加了锁,读并没有加锁。
查询了相关资料,ConcurrentHashMap 读不加锁是因为 Node<K,V> 的 val 是用 volatile 声明的,因此保证了他的可见性,这里的 val 是一个对象。
但是我发现 SynchronizedList 中 list 是用 final 声明的, 而没有使用 volatile。
而根据查询到的资料说 volatile 声明对象或者数组,只能让其引用可见,那么他的元素/属性是如何保证可见呢?
自己做了一些简单的测试, 发现 volatile 声明的对象或者数组,他们的属性或者元素都是可见的(也有说是JIT优化产生的结果)如果 volatile 可以实现读的安全的话,SynchronizedList 是否可以使用 volatile 声明 list 而不给读加锁?

public static void main(String[] args) { VolatileDemo volatileDemo = new VolatileDemo(); new Thread(() -> { long start = System.currentTimeMillis(); System.out.println(start); for (int i = 0; i < 1000; i++) { try { volatileDemo.put(i); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("end"); System.out.println(System.currentTimeMillis() - start); }).start(); new Thread(() -> { for (; ; ) { volatileDemo.printNew(); } }).start(); } static class FlagClass{ boolean hasNew = false; }
2条回答
  • 2021-03-08 17:53

    设计思路不一样,ConcurrentHashMap的读追求的是最终一致性,size()方法尤为明显。

    0 讨论(0)
  • 2021-03-08 18:13

    ConcurrentHashMap 是采用非阻塞算法实现的,就算是在写的情况下,一般也不会加锁。使用cas速度很快,就是实现相当复杂。SynchronizedList 就可以看成是一个普通的list,给方法都加上了同一个锁来保证安全,这样实现效率非常低。至于volatile 只能保证可见性,不能保证线程安全。就像你说的,如果放在引用上,只能保证引用的可见性。

    0 讨论(0)
提交回复