结合安全发布与有效的不可变性来提升性能

探讨了Java中多个线程共享数据时可能遇到的问题,特别是同步带来的性能瓶颈。介绍了分代数据结构技术,用于提高数据结构访问效率,减少同步开销。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用多个 Java 线程之间共享数据的缺点在于数据访问必须同步,从而避免出现不一致的内容视图,后者可能会导致应用程序失败。例如,Hashtable 类的 put()get() 方法是同步的。因为需要实现同步,所以 put()get() 方法在执行时将同时单独地访问数据;否则,应用程序数据结构可能会被破坏。

当某个应用程序的线程频繁访问这些方法,导致线程出现阻塞时,这些方法的同步点将成为瓶颈。每次只能有一个线程获得内容的访问权。而其他线程必须等待。如果线程出现排队等候(如果不是这样,线程能够进行其他有用操作),性能和吞吐量将下降。当性能分析显示同步方法实际上会导致排队点时,对代码进行优化是有益的。

对于很少进行修改的数据,一种被称为分代数据结构(generational data structure)的技术允许您使用较低的 volatile 开销来安全地发布可变数据结构。当数据结构被频繁访问但很少进行修改时,这将获得性能增益。例如,可以使用未同步的数据结构如 HashMap,而不是同步的数据结构如 Hashtable。该技术的关键内容包括:

  1. 发生更新时,制作数据结构的新副本。
  2. 完全填充它。
  3. 使用 volatile 引用将更新安全地发布到所有客户。

使用该技术,getput 操作永远不会在数据结构的同一个示例上同时执行。将确保两个线程不会尝试同时更新数据结构,并且读取线程会始终查看一致的、最新版本的数据。(即使数据被频繁更新,仍可以使用该方法,不过通过改善并发性而获得的性能增益将损失。频繁地重新填充数据结构可能会抵消由消除同步存取器方法而获得的性能增益。)

本文转自: IBM developerWorks 中国
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值