JDK Unsafe类的使用与CAS原子特性

JDK Unsafe类的使用与CAS原子特性

  1. Java.util.concurrent.atomic包,其中包含了大量使用到Unsafe这个类
  2. Java不能直接访问操作系统的底层,而是通过本地方法来访问。

Unsafe类提供了硬件级别的原子操作,主要提供了以下功能

  • 内存操作
  • 字段的定位和修改
  • 挂起和恢复
  • CAS操作(乐观锁)

内存操作

  • 类提供的3个本地方法allocateMemory、reallocteMemory、freeMemory分别用于分配内存、扩充内存和释放内存
//和C语言的3个方法对应/**分配内存**/
public native long allocateMemory(long 1);/**扩充内存**/
public native long reallocateMemory(long 1,long l1);/**释放内存**/
public native void freeMemory(long 1);

字段的定位和修改

  • 可以定位对象字段的内存位置,也可以修改对象的字段值,即使它是私有的

挂起和恢复

  • 将一个线程鼓起是通过park实现的,调用park后,线程会一直阻塞直到超时或者中断等条件的出现
  • unpark可以终止一个挂起的线程,使其恢复正常
  • 整个并发框架中对于线程的挂起操作被封装在LockSupport类中,LockSupport类中有各种版本的pack方法,但是最终都调用了Unsafe.park()方法

CAS操作(乐观锁)

  • CAS(Compare And Swap)比价并交换
  • CAS操作包含三个操作数    内存位置(V)、预期位置(A)、新值(B)
  • 如果内存位置和预期的原值相匹配,那么处理器就会自动将该位置更新为新值。否则,处理器不做任何操作。无论那种情况,它都会在CAS指令之前返回该位置的值
  • 简单讲就是,我认为V应该包含A值,如果复合预期,就将B放到这个位置,否则,不要改变该位置,只告诉我这个位置现在的值就可以
  • Java并发包(java.util.concurrent)中大量使用了CAS操作,涉及到并发的地方都调用了sun.misc.Unsafe类方法进行CAS操作,在Unsafe中是通过compareAndSwapXXX方法实现的。

底层方法如下

/*
*比较obj的offset处内存位置中的值和期望的值,如果相同则更新,此更新是不可中断的*@Param obj需要更新的操作
*@Param offset obj中整型的field偏移量
*@Param expect 希望field中存在的值
*@Param update 如果期望值except与field当前值相同,设置field这个值为新值
*@return 如果field的值将被改变则返回true
*/
public native boolean compareAndSwapInt(Object obj,long offset,int expect,int update)

CountDownLatch

  • CountDownLatch:用于监听某些初始化操作,并且将线程进行阻塞,等初始化执行完毕之后,通知主线程继续工作执行

CyclicBarrier

  • CyclicBarrier:栅栏的概念,多线程的进行阻塞,等待某一个临界值条件满足后,同时执行
  • 比如:将每一个线程比作一个跑步运动员,只有所有的运动员都准备好,才能一起赛跑,只要一个人没有准备好,大家都等等待

Future与Caller回调

  • Future模式:这种模式主要是利用空间换取时间的概念,也就是异步执行(需要开启一个新的线程)
  • Future模式非常适合在处理耗时很长的业务逻辑时进行使用,可以有效的减少系统的响应时间,提高系统的吞吐量

利用设计模式模拟Future

  • Future模式有点类似于商品订单
  • 比如网购的时候,挑选商品,提交订单,付款即可。当订单处理完成之后,在家里等待商品送货上门即可。或者形象的说,当我们发送Ajax请求的时候,页面是异步的进行后台处理,用户无需一直等待请求的结果,可以继续浏览或者操作其他内容

Exchanger多线程间数据交换

  • Exchanger用于进行线程间的数据交换,它提供了一个同步点,在这个同步点,两个线程可以交换彼此的数据
  • 两个线程通过exchange方法交换数据,如果一个线程先执行excange方法,它会一直等待第二个线程也执行exchange方法
  • 当两个线程都达到同步点时,这两个线程就可以交换数据,将本线程生产出来的数据传递给对方
  • 使用的场景:1,遗传算法:遗传算法里需要选两个人作为交换对象,这时会交换两人的数据,并使用交叉规则得出两个人的交换结果;2,文字校对:A和B同时录入数据,然后对A和B进行比较,看是否录入一致,保证数据录入的正确性;

ForkJoin并行框架

  • Frok/Join框架是Java提供的一个用于并行执行任务的框架,将一个大任务分割成若干个小任务,最终汇总每一个小任务的结果后从而得到大任务的结果
  • ForkJoinTask:使用该框架,需要创建一个ForkJoin任务,它提供在任务中执行fork和join操作的机制。一般情况下,我们不需要直接继承ForkJoinTask类,只需要继承他的子类即可
  • RecursiveAction:用于没有返回结果的任务
  • RecursiveTask:用于有返回结果的任务
  • ForkJoinPool:任务ForkJoinTask需要通过ForkJoinPool来执行

Master-Worker并发组件设计模式

  • Master-Worker模式是常用的并发计算模式,他的核心思想是系统由两类进程协作工作:Master和aworker进程
  • Master进程负责接收和分配任务,Worker进程负责处理子任务。当各个Worker子进程处理完成之后,会将结果返回给Master,由Master做归纳和总结
  • 其好处是将一个大任务分解成若干个小任务,并行执行,从而提高系统的吞吐量
  • Master-Worker并发组件设计模拟

Semaphore信号量与限流策略

  • Semaphore信号量非常适合并发访问限制,用于对系统的访问量进行评估。投入资源太大,资源利用率达不到实际效果,纯粹浪费资源;投入资源太小的话,如果一个高峰值的访问量会压垮系统

Semaphore相关概念

  • PV(page view)网站的总访问量,页面浏览量或者点击量,用户每刷新一次就会记录一次
  • UV(unique Visitor)访问网站的一台电脑客户端为一个访客。一般来讲时间上00:00~24:00之内相同ip的客户端记录
  • QPS(query per second)即每秒查询数,qps很大程度上代表了系统业务上的繁忙程度,每次请求的背后,可能对应着多次磁盘I/O,多次网络请求,多个cpu时间片等。通过qps可以非常直观了解当前系统业务情况,一旦当前qps超过所设定的预警阀值,可以考虑增加机器对于集群的扩容,防止压力太大导致宕机,可以根据前期的压力测试,在结合后期压力测试得到估值,再结合后期综合运维情况,估算出阀值
  • RT(response time)请求的响应时间,这个指标非常关键,直接说明前段用户的体验
  • 当然还涉及cpu、内存、网络、磁盘等情况,更细节的问题很多,如select、update、delete/ps等数据库层面的统计。
  • 容量评估:一般来说通过开发、运维、测试、以及业务等相关人员,综合出系统的一系列阀值,然后我们根据关键阀值如qps、rt等,对系统进行有效的变更。
  • 一般来讲,我们进行多轮压力测试以后,可以对系统进行峰值评估,采用所谓的80/20原则,即80%的访问请求将在20%的时间内达到。这样我们可以根据系统对应的PV计算出峰值qps。
  • 峰值qps= (总PV × 80%)/ (60 × 60 × 24 × 20%)
  • 然后在将总的峰值qps除以单台机器所能承受的最高的qps值,就是所需要机器的数量:机器数 = 总的峰值qps / 压测得出的单机极限qps
  • 当然不排除系统在上线前进行大型促销活动,或者双十一、双十二热点事件、遭受到DDos攻击等情况,系统的开发和运维人员急需要了解当前系统运行的状态和负载情况,一般都会有后台系统去维护。    

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/447343.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

写软件不是造汽车

写软件和做其他事情是不一样的。当我们制造别的东西的时候——像汽车、玩具、椅子、画作、甚至包括数字产品如平面图片和3D模型——我们做出来的成品就是最终的结果。而开发软件则不是,我们做出来的产品永远不可能有最终的结果——我们需要向计算机解释如何根据任意…

网站盈利的10种方式

如果你有自己的网站,而且已经有了不少的流量,你肯定会开始考虑如何通过这个网站来挣一些钱。 在这篇文章中,我会向大家介绍网站最常见的10种盈利方式。 1.按点击付费广告 在网站上展示一个按点击付费的广告横幅是最简单的盈利方式&#xff…

Redis数据的类型

Redis一共分为五种基本数据类型:String、Hash、List、Set、Zset. string 内部编码有三种,raw,embstr,int String 是二进制的。可以存储序列化对象,图片,字符串,数值等 set和get方法 &#x…

Redis高级命令与特性以及单点模式的介绍

高级命令 keys * 返回满足条件的所有key,可以模糊匹配exists 是否存在指定的keypersist 取消过期时间select 选择数据库 (0-15,总共16个数据库)move key index 将当前数据库的 key 移动到给定的数据库 db 当中randomkey 随机返回…

同为程序员 为什么我的工资最低

我看着工资单上每一个开发团队成员的薪水,慢慢地我不能保持淡定了。 而当我看到我的工资排名是倒数的时候——靠近最后一名——我不由得倒抽一口冷气。就像圣诞故事中的那个可爱的小男孩Ralphie ,想买气枪却被忽悠会有危险一样,我也不断忽悠…

redis.conf配置文件详解

基本配置 daemonize no #是否以后台进程启动databases 16 #创建database的数量(默认选中的是database 0)save 900 1 #刷新快照到硬盘中,必须满足两者要求才会触发,即900秒之后至少1个关键字发生变化save 300 10 #必须是300秒之后至少10个关键字发生变…

用Unix的设计思想来应对多变的需求

摘要:无论是Unix设计,还是面向对象设计,还是别的什么如SOA,ECB,消息,事件,MVC,网络七层模型,数据库设计,等等,他们都在干三件事——解耦&#xff…

有关编程的12个猜想

摘要:编程世界的将来如何目前仍难预料,但可以肯定的一点是技术一直在加速发展。本文搜罗出12个独特的编程视角猜想,一起来看看有哪些猜想在不久的将来就能变为现实。 编程世界的将来如何目前仍难预料,但可以肯定的一点是技术一直…

面试中如何剔除“鱼目混珠”程序员?

公司招聘面试事宜是一个耗时耗钱的项目,从挑选简历开始,还要花更多的时间面试候选人。有的时候这些人才机构会向你保证这些人都是Java天才、SQL专家、堆栈开发者等等,但实际上真实情况远不及你想想的。对于一个公司来说,执行招聘面…

java容器相关问题

同步类容器 1,这些复合操作在多线程并发地修改容器时,可能会表现出意外的行为,最经典的便是ConcurrentModificationException,原因是当容器迭代的过程中,被并发的修改了内容,这是由于早期迭代器设计的时候…

趣文:如果编程语言是车

C语言是全能手,小巧,强大,所向披靡,可靠,任何事情都能对付。 C是新的C,双倍的能力,双倍的尺寸,适应险恶的环境,但是你如果没练好就去驾驶,很可能会撞车。 C#是…

开发者应该了解的API技术清单!

摘要:有人说,有API的地方就有App,借助这些API开发者轻松构建出一款应用,极大地提高开发效率和开发质量。文中整理了一份API服务清单,内容涵盖:监控/调试、 CDN 、数据库、仪表盘、支付、通信等方面&#xf…

提高程序员职场价值的10大技巧

如果你已经是个很牛叉的程序员,但是依然觉得觉得还不够的话,欢迎阅读此文。本文旨在帮助各位更上一层楼。 你是不是觉得自己已经掌握了所有的编程技巧?别太自以为是了! 会写代码的确很重要,但是要拿到更好薪水&#…

google python的风格规范

点击链接,查看内容

IT人应当知道的10个行业小内幕

如果你打算从事IT行业或刚进入这个行业,也许本文下面的小内幕会吓到你,因为这些事平常都不会公开讨论的。如果你是IT资深人士,或许你已经遇到其中的大部分了。如果你愿意,请一起来参与讨论吧。 这些内幕大多数是针对网络管理员、…

Volatile原子性一致性JVM指令重排

概念 Volatile概念:Volatile关键字的主要作用是使变量在多个线程间可见。作用: 在多线程间可以进行变量的变更,使得线程间进行数据的共享可见 阻止指令重排序,happens-before package com.example.core.cas;import com.example.c…

Java JUC工具类--CyclicBarrier

CyclicBarrier:栅栏的概念,多线程的进行阻塞,等待某一个临界值条件满足后,同时执行 类比:每个线程代表一个跑步运动员,当运动员都准备好后,才一起出发,只要有一个人没有准备好&#…

Java JUC工具类--Future

Future模式,也是非常经典的设计模式,这种模式主要就利用空间换时间的概念,也就是说异步执行(需要开启一个新的线程)在互联网高并发的应用服务中,我们随处可见这种理念和代码,主要就是使用了这种…

Java JUC工具类--ForkJoin

ForkJoin Fork/Join框架是JAVA7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架Fork/Join中两个重要的类 ForkJoinTask:使用该框架,需要创建一个ForkJoin任务…