全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Java8新特性之StampedLock_动力节点Java学院整理

Java8就像一个宝藏,一个小的API改进,也足与写一篇文章,比如同步,一直是多线程并发编程的一个老话题,相信没有人喜欢同步的代码,这会降低应用的吞吐量等性能指标,最坏的时候会挂起死机,但是即使这样你也没得选择,因为要保证信息的正确性。所以本文决定将从synchronized、Lock到Java8新增的StampedLock进行对比分析,相信StampedLock不会让大家失望。

synchronized

在java5之前,实现同步主要是使用synchronized。它是Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。

有四种不同的同步块:

1.实例方法

2.静态方法

3.实例方法中的同步块

4.静态方法中的同步块

大家对此应该不陌生,所以不多讲了,以下是代码示例

synchronized(this)
// do operation
}

小结:在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁,但是随着Java SE1.6对Synchronized进行了各种优化之后,性能上也有所提升。

Lock

它是Java 5在java.util.concurrent.locks新增的一个API。

Lock是一个接口,核心方法是lock(),unlock(),tryLock(),实现类有ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock;

ReentrantReadWriteLock, ReentrantLock 和synchronized锁都有相同的内存语义。

与synchronized不同的是,Lock完全用Java写成,在java这个层面是无关JVM实现的。Lock提供更灵活的锁机制,很多synchronized 没有提供的许多特性,比如锁投票,定时锁等候和中断锁等候,但因为lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally{}中

下面是Lock的一个代码示例

rwlock.writeLock().lock();
try {
// do operation
} finally {
rwlock.writeLock().unlock();
}

小结:比synchronized更灵活、更具可伸缩性的锁定机制,但不管怎么说还是synchronized代码要更容易书写些

StampedLock

它是java8在java.util.concurrent.locks新增的一个API。

ReentrantReadWriteLock 在沒有任何读写锁时,才可以取得写入锁,这可用于实现了悲观读取(Pessimistic Reading),即如果执行中进行读取时,经常可能有另一执行要写入的需求,为了保持同步,ReentrantReadWriteLock 的读取锁定就可派上用场。

然而,如果读取执行情况很多,写入很少的情况下,使用 ReentrantReadWriteLock 可能会使写入线程遭遇饥饿(Starvation)问题,也就是写入线程吃吃无法竞争到锁定而一直处于等待状态。

StampedLock控制锁有三种模式(写,读,乐观读),一个StampedLock状态是由版本和模式两个部分组成,锁获取方法返回一个数字作为票据stamp,它用相应的锁状态表示并控制访问,数字0表示没有写锁被授权访问。在读锁上分为悲观锁和乐观锁。

所谓的乐观读模式,也就是若读的操作很多,写的操作很少的情况下,你可以乐观地认为,写入与读取同时发生几率很少,因此不悲观地使用完全的读取锁定,程序可以查看读取资料之后,是否遭到写入执行的变更,再采取后续的措施(重新读取变更信息,或者抛出异常) ,这一个小小改进,可大幅度提高程序的吞吐量!!

下面是java doc提供的StampedLock一个例子

class Point {
 private double x, y;
 private final StampedLock sl = new StampedLock();
 void move(double deltaX, double deltaY) { // an exclusively locked method
  long stamp = sl.writeLock();
  try {
  x += deltaX;
  y += deltaY;
  } finally {
  sl.unlockWrite(stamp);
  }
 }
 //下面看看乐观读锁案例
 double distanceFromOrigin() { // A read-only method
  long stamp = sl.tryOptimisticRead(); //获得一个乐观读锁
  double currentX = x, currentY = y; //将两个字段读入本地局部变量
  if (!sl.validate(stamp)) { //检查发出乐观读锁后同时是否有其他写锁发生?
  stamp = sl.readLock(); //如果没有,我们再次获得一个读悲观锁
  try {
   currentX = x; // 将两个字段读入本地局部变量
   currentY = y; // 将两个字段读入本地局部变量
  } finally {
   sl.unlockRead(stamp);
  }
  }
  return Math.sqrt(currentX * currentX + currentY * currentY);
 }
//下面是悲观读锁案例
 void moveIfAtOrigin(double newX, double newY) { // upgrade
  // Could instead start with optimistic, not read mode
  long stamp = sl.readLock();
  try {
  while (x == 0.0 && y == 0.0) { //循环,检查当前状态是否符合
   long ws = sl.tryConvertToWriteLock(stamp); //将读锁转为写锁
   if (ws != 0L) { //这是确认转为写锁是否成功
   stamp = ws; //如果成功 替换票据
   x = newX; //进行状态改变
   y = newY; //进行状态改变
   break;
   }
   else { //如果不能成功转换为写锁
   sl.unlockRead(stamp); //我们显式释放读锁
   stamp = sl.writeLock(); //显式直接进行写锁 然后再通过循环再试
   }
  }
  } finally {
  sl.unlock(stamp); //释放读锁或写锁
  }
 }
 }

小结:

StampedLock要比ReentrantReadWriteLock更加廉价,也就是消耗比较小。

StampedLock与ReadWriteLock性能对比

下图是和ReadWritLock相比,在一个线程情况下,是读速度其4倍左右,写是1倍。

下图是六个线程情况下,读性能是其几十倍,写性能也是近10倍左右:

下图是吞吐量提高:

总结

1、synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定;

2、ReentrantLock、ReentrantReadWriteLock,、StampedLock都是对象层面的锁定,要保证锁定一定会被释放,就必须将unLock()放到finally{}中;

3、StampedLock 对吞吐量有巨大的改进,特别是在读线程越来越多的场景下;

4、StampedLock有一个复杂的API,对于加锁操作,很容易误用其他方法;

5、当只有少量竞争者的时候,synchronized是一个很好的通用的锁实现;

6、当线程增长能够预估,ReentrantLock是一个很好的通用的锁实现;


# java8新特性  # java8  # stampedlock  # Java使用StampedLock实现高效读写功能  # Java中的StampedLock实现原理详解  # Java中的ReentrantLock、ReentrantReadWriteLock、Stamped  # Java利用StampedLock实现读写锁的方法详解  # java并发编程StampedLock高性能读写锁详解  # Java并发编程之StampedLock锁介绍  # Java StampedLock实现原理与最佳实践记录  # 是一个  # 它是  # 情况下  # 很好  # 多线程  # 的是  # 都是  # 这是  # 更灵活  # 这一  # 是在  # 都有  # 就必须  # 就像  # 你可以  # 最多  # 你也  # 是由  # 很多人  # 不多 


相关文章: 香港服务器租用每月最低只需15元?  建站主机服务器选型指南与性能优化方案解析  宝塔Windows建站如何避免显示默认IIS页面?  C++用Dijkstra(迪杰斯特拉)算法求最短路径  网站制作话术技巧,网站推广做的好怎么话术?  建站之星如何实现PC+手机+微信网站五合一建站?  如何选择靠谱的建站公司加盟品牌?  如何选择最佳自助建站系统?快速指南解析优劣  如何选择高性价比服务器搭建个人网站?  如何在景安云服务器上绑定域名并配置虚拟主机?  制作充值网站的软件,做人力招聘为什么要自己交端口钱?  学校建站服务器如何选型才能满足性能需求?  C++如何使用std::optional?(处理可选值)  建站之星后台管理:高效配置与模板优化提升用户体验  如何快速搭建安全的FTP站点?  中山网站推广排名,中山信息港登录入口?  矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?  如何在阿里云部署织梦网站?  如何生成腾讯云建站专用兑换码?  免费视频制作网站,更新又快又好的免费电影网站?  电视网站制作tvbox接口,云海电视怎样自定义添加电视源?  品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?  建站之星图片链接生成指南:自助建站与智能设计教程  哈尔滨网站建设策划,哈尔滨电工证查询网站?  如何通过VPS建站无需域名直接访问?  深圳防火门网站制作公司,深圳中天明防火门怎么编码?  制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?  广东企业建站网站优化与SEO营销核心策略指南  专业网站设计制作公司,如何制作一个企业网站,建设网站的基本步骤有哪些?  网站建设制作、微信公众号,公明人民医院怎么在网上预约?  建站之星导航菜单设置与功能模块配置全攻略  成都响应式网站开发,dw怎么把手机适应页面变成网页?  高端网站建设与定制开发一站式解决方案 中企动力  一键制作网站软件下载安装,一键自动采集网页文档制作步骤?  免费公司网站制作软件,如何申请免费主页空间做自己的网站?  重庆网站制作公司哪家好,重庆中考招生办官方网站?  如何快速生成橙子建站落地页链接?  建站之星ASP如何实现CMS高效搭建与安全管理?  javascript中对象的定义、使用以及对象和原型链操作小结  建站之星如何快速解决建站难题?  如何用5美元大硬盘VPS安全高效搭建个人网站?  b2c电商网站制作流程,b2c水平综合的电商平台?  网站插件制作软件免费下载,网页视频怎么下到本地插件?  如何在Windows环境下新建FTP站点并设置权限?  制作公司内部网站有哪些,内网如何建网站?  制作网站怎么制作,*游戏网站怎么搭建?  如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?  如何在建站主机中优化服务器配置?  天河区网站制作公司,广州天河区如何办理身份证?需要什么资料有预约的网站吗?  Android使用GridView实现日历的简单功能 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。