java安装_Java 8 StampedLocks与ReadWriteLocks和同步

java安装

java安装

Blog_key_

同步部分就像访问您的岳父母。 您希望尽可能少出现。 当涉及到锁定规则时,它们是相同的–您想花费最短的时间在关键区域内获取锁定,以防止形成瓶颈。

锁定的核心语言习惯用法一直是用于方法和离散块的synced关键字。 这个关键字实际上已硬连接到HotSpot JVM。 我们在代码中分配的每个对象,无论是String,Array还是成熟的JSON文档,都在本机GC级别的标头中内置锁定功能。 对于JIT编译器(根据特定锁的特定状态和争用级别来编译和重新编译字节码)也是如此。

同步块的问题在于它们全有还是全无-关键部分中不能有多个线程。 在消费者/生产者方案中,这尤其令人b舌,其中一些线程试图专门编辑一些数据,而另一些线​​程只是试图读取它并且可以共享访问权限。

ReadWriteLocks应该是实现此目的的完美解决方案。 您可以指定哪些线程会阻塞其他所有人(作家),以及哪些线程可以与其他人一起使用以消费内容(读者)。 一个圆满的结局? 不怕。

与同步块不同,RW锁不是JVM内置的,并且具有与凡人代码相同的功能。 尽管如此,要实现锁定习惯,您仍然需要指示CPU自动执行特定操作或以特定顺序执行操作,以避免出现竞争情况。 传统上,这是通过进入JVM的神奇门户漏洞- 不安全的类来完成的。 RW锁使用比较和交换(CAS)操作将值直接设置到内存中,作为其线程排队算法的一部分。

即便如此,RWLocks仍然不够快,有时甚至被证明确实很,以至于不值得打扰。 但是,正在寻求帮助,JDK的好伙伴们没有放弃,现在又有了新的StampedLock 。 该RW锁采用了Java 8 JDK中添加的一组新算法和内存防护功能,以帮助使此锁更快,更可靠。

它履行诺言吗? 让我们来看看。

使用锁。 从表面上看,StampedLocks的使用更为复杂。 他们采用的邮票概念是很长的值,可以用作任何锁定/解锁操作所使用的票证。 这意味着要解锁R / W操作,您需要为其传递相关的锁定标记。 通过错误的印章,您将面临例外甚至更糟的意外风险。

另一个需要牢记的关键是,与RWLocks不同,StampedLocks不可重入。 因此,尽管它们可能更快,但它们有一个缺点,那就是线程现在可能会陷入僵局。 实际上,这意味着比以往任何时候都更应该确保锁和图章不会逸出其封闭的代码块。

long stamp = lock.writeLock();  //blocking lock, returns a stamp

try {

  write(stamp); // this is a bad move, you’re letting the stamp escape
}

finally {

  lock.unlock(stamp);// release the lock in the same block - way better
}

我对这种设计的另一个讨厌之处是,邮票被用作长期价值,对您实际上没有任何意义。 我希望使用锁定操作来返回一个描述印记的对象-它的类型(R / W),锁定时间,所有者线程等。这会使调试和记录更加容易。 但是,这可能是有意的,它旨在防止开发人员在代码的不同部分之间传递标记,并且还节省了分配对象的成本。

乐观锁。 就此锁的新功能而言,最重要的部分是新的乐观锁模式。 研究和实践经验表明,读操作在大多数情况下都无法与写操作抗衡。 结果,获得一个成熟的读锁可能被证明是过大的。 更好的方法可能是继续执行读取,并在读取的最后查看该值是否实际上已被修改。 如果是这种情况,您可以重试读取,或升级到较重的锁。

long stamp = lock.tryOptimisticRead(); // non blocking

read();

if(!lock.validate(stamp)){ // if a write occurred, try again with a read lock

  long stamp = lock.readLock();

  try {

    read();
  }
  finally {
   
    lock.unlock(stamp);
  }
}

选择锁的最大麻烦之一是,其在生产中的实际行为将根据应用程序状态而有所不同。 这意味着锁定习语的选择不能在真空中完成,而必须考虑代码将在其下执行的实际条件。

并发读取器线程与写入器线程的数量将更改您应使用的锁–同步段或RW锁。 由于这些数字在JVM的生命周期中会发生变化,因此这变得更加困难,具体取决于应用程序状态和线程争用。

为了说明这一点,我在不同的竞争级别和R / W线程组合下对四种锁定模式进行了压力测试-同步,RW锁定,Stamped RW锁定和RW乐观锁定。 读取器线程将消耗计数器的值,而写入器线程将其从0递增到1M。

5个读取器与5个写入器堆叠5个并发读取器和5个写入器线程,我们看到加盖的锁发光,与同步相比,性能提高了3倍。 RW锁定也表现良好。 奇怪的是,乐观锁在表面上应该是最快的,但实际上却是最慢的

04

1 0个读者与10个作家:接下来,我将争用级别提高到10个作家和10个读者线程。 在这里,事情开始发生重大变化。 RW锁现在比在相同级别上执行的加盖和同步锁一个数量级。 请注意,令人惊奇的是乐观锁仍然是慢速加盖的RW锁。

01

16位读者与4位作家:接下来,我保持了较高的竞争水平,同时使平衡趋于有利于读者线程:16位读者与4位作家。 RW锁继续说明了其被替换的原因-速度慢一百倍。 Stamped和Optimistic的性能很好,同步性也不差。

02

19位读者与1位读者:最后,我研究了单个作者线程对19位读者的影响。 注意,结果要慢得多,因为单线程需要更长的时间才能完成工作。 在这里,我们得到一些非常有趣的结果。 毫不奇怪,RW锁需要无穷大才能完成。 但是,冲压锁定的性能并没有好得多……乐观锁定显然是赢家,比RW锁定高100倍。即使如此,请记住,这种锁定方式可能会使您失败,因为在此期间可能会发生写入器。 我们忠实的老客户,同步化继续取得可喜的成果。

03

完整的结果可以在这里找到……硬件:MBP四核i7。

基准代码可以在这里找到。

结论

似乎平均而言,最佳性能仍然是由内部同步锁提供的。 即使这样,这里的意思并不是说它将在所有情况下都表现最佳。 主要是为了表明,将代码投入生产之前,应该基于测试预期的争用级别以及读取器和写入器线程之间的划分来选择锁定习惯用法。 否则,您将冒着严重的生产 调试痛苦的风险。

在此处了解有关StampedLocks的更多信息

对基准有疑问,意见或建议吗? 让我知道!

翻译自: https://www.javacodegeeks.com/2014/06/java-8-stampedlocks-vs-readwritelocks-and-synchronized.html

java安装

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值