HashTable读操作为什么要加锁

CopyAndWriteArrayList的读操作就不用加锁,因为写操作会拷贝数组不会对原数组产生影响,所以读操作不加锁。
那么HashTable如果不加锁会出现什么问题呢,如果只是读取到其他线程修改后的数据,在某些业务场景下也没有问题吧。
这是不是后来又出现ConcurrentHashMap的原因,写操作加锁,读操作不加锁并通过volatile保证可见性,同时提高了读写的性能。
请大神解惑。


回答:

HashTable是一个比较老的库,你可以发现JDK中对于老类库的线程同步方案都是直接加锁,这是一个比较简单的方案,所以直接那么做了。

当Java越来越流行,社区想要Java拥有更强的性能之后,也就是JDK5之后才出现各种方式的线程同步方案,所以这仅仅是一个历史问题罢了,不必深究。

你可以将更多的精力放在新方案的设计思想上面,比如你提到过的:CopyAndWriteArrayList 和 ConcurrentHashMap。

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。


回答:

我认为这是一种线程安全的设计思维吧,就是指我在读一个资源的时候我希望这个资源不会被修改。
这也是为什么会有读写锁这个东西。HashTable是一个很旧的东西,或许设计者在设计之初就是这种思考,在后面的发展中就是优化了。(题外话:就想LinkedList的作者所说,他虽然发明了这个数据结构,但是他从来都不用)在我如今的项目中,大量的使用了读写锁的思想,就是不希望我在读的过程中数据有所改变。如果你没有这方面的限制,就不必在读的时候进行加锁的设计。


回答:

我觉得这个问题不能考虑得过于深入,感觉特别容易陷进去。多线程的运行是复杂的,要考虑到每一种事故也挺困难的。不过好处是遵守一定的规则可以避免一些问题。就说读写锁吧,互斥可以分为读读、读写、写写、写读。而读写锁,也仅仅只是打开了读读,读写可没有打开,在读取数据的时候不能写入,这应该是底层需要遵守的基本规则,否则可能发生数据争用,造成未知情况。写入时复制之所以能放开读写,那是因为它在每一次写入时都会拷贝一份来操作,并不会在原数据上操作,即使同时读写,那也是读一份,写一份,而写完后赋值可以看作是具有原子性的,所以避免的数据争用,但对高频写,这个类就不那么友好。

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。


回答:

我觉得应该是HashTable的作用来决定的,可能当初的设计者的目的就是实现线程的绝对安全,所以所有的方法都使用了悲观锁.但是因为效率低下的原因,后来才出现了ConcurrentHashMap这样的数据结构

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。

以上是 HashTable读操作为什么要加锁 的全部内容, 来源链接: utcz.com/p/944520.html

回到顶部