电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Java CAS基本實現原理代碼實例解析

瀏覽:52日期:2022-08-27 17:04:49

一、前言

了解CAS,首先要清楚JUC,那么什么是JUC呢?JUC就是java.util.concurrent包的簡稱。它有核心就是CAS與AQS。CAS是java.util.concurrent.atomic包的基礎,如AtomicInteger、AtomicBoolean、AtomicLong等等類都是基于CAS。

什么是CAS呢?全稱Compare And Swap,比較并交換。CAS有三個操作數,內存值V,舊的預期值E,要修改的新值N。當且僅當預期值E和內存值V相同時,將內存值V修改為N,否則什么都不做。

Java CAS基本實現原理代碼實例解析

二、實例

如果我們需要對一個數進行加法操作,應該怎樣去實現呢?我們模擬多個線程情況下進行操作。

ThreadDemo.java 實現一個Runnable接口

package com.spring.security.test;public class ThreadDemo implements Runnable {private int count = 0;@Overridepublic void run() {for (int i = 0; i < 100; i++) {addCount();}}private void addCount() {count++;}public int getCount() {return count;}}

ThreadTest.java 創建線程池,提交10個線程執行,預期結果應該是1000

package com.spring.security.test;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class ThreadTest {public static void main(String[] args) {ExecutorService threadPool = Executors.newFixedThreadPool(10);ThreadDemo threadDemo = new ThreadDemo();for (int i = 0; i < 10; i++) {threadPool.submit(threadDemo);} threadPool.shutdown();System.out.println(threadDemo.getCount());}}

運行結果:874 或其他,與預期結果不符合。

執行出來的結果并不是想象中的結果。這是為什么呢?這跟線程的執行過程有關。

Java CAS基本實現原理代碼實例解析

所以我們需要在改變count,將值從高速緩沖區刷新到主內存后,讓其他線程重新讀取主內存中的值到自己的工作內存。

此時可以用volatile關鍵字。它的作用是保證對象在內存中的可見性。

修改ThreadDemo中的count字段

private volatile int count = 0;

此時執行結果:900 或其他,與預期結果不符合。

此時還是并未得出正確執行結果。為什么?聽我細細道來。

線程安全主要體現在三個方面:

原子性:提供了互斥訪問,同一時刻只能有一個線程對它進行操作 可見性:一個線程對主內存的修改可以及時的被其他線程觀察到 有序性:一個線程觀察其他線程中的指令執行順序,由于指令重排序的存在,該觀察結果一般雜亂無序

目前可見性已經實現了,缺少原子性的操作,因為同一時刻,多個線程對其操作,會將改動后的最新值讀取到自己的工作內存進行操作,最終只能得到后一個執行線程操作的結果,所以相當于少了一步操作,就會造成數據的不一致。

此時可以使用JUC的Atomic包下面的類來進行操作。

Java CAS基本實現原理代碼實例解析

Atomic類是使用CAS+volatile來實現原子性與可見性的。

我們來改造一下TheadDemo.java中的實現方法

package com.spring.security.test;import java.util.concurrent.atomic.AtomicInteger;public class ThreadDemo implements Runnable {private AtomicInteger count = new AtomicInteger(0);@Overridepublic void run() {for (int i = 0; i < 100; i++) {// 遞增count.getAndIncrement();}}public int getCount() {return count.get();}}

執行結果: 1000,符合預期值。

Java CAS基本實現原理代碼實例解析

接下來我們來分析一下AtomicInteger類的源碼:

private static final Unsafe unsafe = Unsafe.getUnsafe();private static final long valueOffset;static { try { valueOffset = unsafe.objectFieldOffset (AtomicInteger.class.getDeclaredField('value')); } catch (Exception ex) { throw new Error(ex); }}private volatile int value;

Unsafe類是不安全的類,它提供了一些底層的方法,我們是不能使用這個類的。AtomicInteger的值保存在value中,而valueOffset是value在內存中的偏移量,利用靜態代碼塊使其類一加載的時候就賦值。value值使用volatile,保證其可見性。

/** * Atomically increments by one the current value. * * @return the previous value */ public final int getAndIncrement() { return unsafe.getAndAddInt(this, valueOffset, 1); }

public final int getAndAddInt(Object var1, long var2, int var4) {int var5;do {var5 = this.getIntVolatile(var1, var2);} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));return var5;}

var1表示當前對象,var2表示value在內存中的偏移量,var4為增加的值。var5為調用底層方法獲取value的值

compareAndSwapInt方法通過var1和var2獲取當前內存中的value值,并與var5進行比對,如果一致,就將var5+var4的值賦給value,并返回true,否則返回false

由do while語句可知,如果這次沒有設置進去值,就重復執行此過程。這一過程稱為自旋。

compareAndSwapInt是JNI(Java Native Interface)提供的方法,可以是其他語言寫的。

三、與synchronized比較

使用synchronized進行加法:

package com.spring.security.test;public class ThreadDemo implements Runnable {private int count = 0;@Overridepublic void run() {for (int i = 0; i < 100; i++) {// 遞增synchronized (ThreadDemo.class) {count++;}}}public int getCount() {return count;}}

運行結果: 1000,符合預期值。

444

使用synchronized和AtomicInteger都能得到預期結果,但是他們之間各有什么劣勢呢?

synchronized是重量級鎖,是悲觀鎖,就是無論你線程之間發不發生競爭關系,它都認為會發生競爭,從而每次執行都會加鎖。

在并發量大的情況下,如果鎖的時間較長,那將會嚴重影響系統性能。

CAS操作中我們可以看到getAndAddInt方法的自旋操作,如果長時間自旋,那么肯定會對系統造成壓力。而且如果value值從A->B->A,那么CAS就會認為這個值沒有被操作過,這個稱為CAS操作的'ABA'問題。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Java
相關文章:
主站蜘蛛池模板: 通风气楼_通风天窗_屋顶风机-山东美创通风设备有限公司 | 集装箱展厅-住人集装箱住宿|建筑|房屋|集装箱售楼处-山东锐嘉科技工程有限公司 | 液氮罐_液氮容器_自增压液氮罐_杜瓦瓶_班德液氮罐厂家 | 营养师网,营养师考试时间,报名入口—网站首页 | 超声波清洗机_超声波清洗机设备_超声波清洗机厂家_鼎泰恒胜 | 辐射色度计-字符亮度测试-反射式膜厚仪-苏州瑞格谱光电科技有限公司 | 沈阳液压泵_沈阳液压阀_沈阳液压站-沈阳海德太科液压设备有限公司 | 焊锡丝|焊锡条|无铅锡条|无铅锡丝|无铅焊锡线|低温锡膏-深圳市川崎锡业科技有限公司 | 蒸汽吸附分析仪-进口水分活度仪|康宝百科 | 股指期货-期货开户-交易手续费佣金加1分-保证金低-期货公司排名靠前-万利信息开户 | bng防爆挠性连接管-定做金属防爆挠性管-依客思防爆科技 | 上海软件开发-上海软件公司-软件外包-企业软件定制开发公司-咏熠科技 | 不锈钢复合板厂家_钛钢复合板批发_铜铝复合板供应-威海泓方金属复合材料股份有限公司 | 护腰带生产厂家_磁石_医用_热压护腰_登山护膝_背姿矫正带_保健护具_医疗护具-衡水港盛 | 煤矿支护网片_矿用勾花菱形网_缝管式_管缝式锚杆-邯郸市永年区志涛工矿配件有限公司 | 高中学习网-高考生信息学习必备平台| 广州二手电缆线回收,旧电缆回收,广州铜线回收-广东益福电缆线回收公司 | 电镀电源整流器_高频电解电源_单脉双脉冲电源 - 东阳市旭东电子科技 | 济南侦探调查-济南调查取证-山东私家侦探-山东白豹调查咨询公司 密集架|电动密集架|移动密集架|黑龙江档案密集架-大量现货厂家销售 | 对夹式止回阀_对夹式蝶形止回阀_对夹式软密封止回阀_超薄型止回阀_不锈钢底阀-温州上炬阀门科技有限公司 | 电力测功机,电涡流测功机,磁粉制动器,南通远辰曳引机测试台 | 防水套管|柔性防水套管|伸缩器|伸缩接头|传力接头-河南伟创管道 防水套管_柔性防水套管_刚性防水套管-巩义市润达管道设备制造有限公司 | LED投光灯-工矿灯-led路灯头-工业灯具 - 山东普瑞斯照明科技有限公司 | 酒吧霸屏软件_酒吧霸屏系统,酒吧微上墙,夜场霸屏软件,酒吧点歌软件,酒吧互动游戏,酒吧大屏幕软件系统下载 | 淘剧影院_海量最新电视剧,免费高清电影随心观看 | 北京环球北美考试院【官方网站】|北京托福培训班|北京托福培训 | 多米诺-多米诺世界纪录团队-多米诺世界-多米诺团队培训-多米诺公关活动-多米诺创意广告-多米诺大型表演-多米诺专业赛事 | 传递窗_超净|洁净工作台_高效过滤器-传递窗厂家广州梓净公司 | 深圳快餐店设计-餐饮设计公司-餐饮空间品牌全案设计-深圳市勤蜂装饰工程 | 智慧食堂_食堂管理系统_食堂订餐_食堂消费系统—客易捷 | 硬度计,金相磨抛机_厂家-莱州华煜众信试验仪器有限公司 | 带压开孔_带压堵漏_带压封堵-菏泽金升管道工程有限公司 | 流量检测仪-气密性检测装置-密封性试验仪-东莞市奥图自动化科技有限公司 | 酒水灌装机-白酒灌装机-酒精果酒酱油醋灌装设备_青州惠联灌装机械 | 高考志愿规划师_高考规划师_高考培训师_高报师_升学规划师_高考志愿规划师培训认证机构「向阳生涯」 | 电伴热系统施工_仪表电伴热保温箱厂家_沃安电伴热管缆工业技术(济南)有限公司 | 神超官网_焊接圆锯片_高速钢锯片_硬质合金锯片_浙江神超锯业制造有限公司 | 空心明胶胶囊|植物胶囊|清真胶囊|浙江绿键胶囊有限公司欢迎您! | LOGO设计_品牌设计_VI设计 - 特创易 | 经济师考试_2025中级经济师报名时间_报名入口_考试时间_华课网校经济师培训网站 | 爱德华真空泵油/罗茨泵维修,爱发科-比其尔产品供应东莞/杭州/上海等全国各地 |