CASCAS姣旇緝鍜屼氦鎹紙CAS锛夌殑姒傚康锛屾槸涓€绉嶅師瀛愭搷浣滐紝鍙互鐢ㄦ潵瀹炵幇澶氱嚎绋嬬紪绋嬩腑涓嶉棿鏂殑鏁版嵁浜ゆ崲鎿嶄綔锛屼粠鑰岄伩鍏嶅绾跨▼鏃堕噸鍐欎竴涓煇浜涙暟鎹紝鐢变簬鎵ц椤哄簭鐨勪笉纭畾鎬у拰涓柇鐨勪笉鍙娴嬫€э紝浼氬嚭鐜版暟鎹笉涓€鑷寸殑闂銆傝鎿嶄綔灏嗗唴瀛樹腑鐨勫€间笌鎸囧畾鏁版嵁杩涜姣旇緝锛屽綋鍊肩浉鍚屾椂锛屽皢鍐呭瓨涓殑鏁版嵁鏇挎崲涓烘柊鍊笺€備互涓婂唴瀹规憳鑷淮鍩虹櫨绉戙€備粠鎻忚堪鐨勬渶鍚庝竴鍙ユ垜浠彲浠ョ湅鍑篊AS鐨勬€濇兂銆傛棦鐒惰杩涜姣旇緝锛岄偅涔堢鍙蜂袱杈规槸鍚﹂渶瑕佷袱涓€硷紝姣旇緝鍚庨渶瑕佹浛鎹㈡槸鍚﹂渶瑕佷竴涓€煎憿锛熸墍浠AS鏈?涓弬鏁帮紝鍒嗗埆鏄疺銆丒xpected鍜孨ewValue銆俈涓哄師濮嬪唴瀛樹腑鐨勫€硷紙瑕佹敼鍙樼殑鍊硷級锛孍xpected涓烘寚瀹氭暟鎹紙鏈熸湜鍊硷級锛孨ewValue涓烘柊鍊硷紙鏈€缁堢粨鏋滅殑鍊硷級銆備唬鐮佽〃绀哄涓嬶細cas(V,Expected,NewValue){if(V==Expected){V==NewValue;}//retryorstop}涓轰粈涔圕ASsynchronized浣跨敤鐙崰鏂瑰紡鑾峰彇鍏变韩鍙橀噺锛屽綋鏈夊叾浠栫嚎绋嬫兂瑕佽幏鍙栧叡浜彉閲忔椂锛屽彧鑳芥寕璧风瓑寰咃紝鎵€浠ynchronized鏄偛瑙傞攣锛岀嚎绋嬭幏鍙杘r鎮茶閿佸鑷寸殑閲婃斁閿佷細瀵艰嚧鎬ц兘闂锛涜€孋AS鎿嶄綔鏄綋澶氫釜绾跨▼灏濊瘯浣跨敤CAS鎿嶄綔鍏变韩鍙橀噺鏃讹紝姣忎釜绾跨▼閮戒笉浼氬洜涓哄叾浠栫嚎绋嬫鍦ㄦ搷浣滃叡浜彉閲忚€岃鎸傝捣锛屾墍浠AS鎿嶄綔鏄竴绉嶄箰瑙傞攣锛屼絾鏈€缁堝彧鏈夊叾涓竴涓嚎绋嬪彲浠ヨ繍琛屾垚鍔燂紝鍏朵粬绾跨▼浼氬け璐ャ€傚叿浣撳悗缁槸閲嶅惎璇曡繕鏄仠灏辩湅浣犵殑浜嗐€傜畝鍗曞湴璇达紝瀹冩彁楂樹簡鏁堢巼銆傛偛瑙傞攣鍜屼箰瑙傞攣閮芥槸涓€绉嶆€濈淮鏂瑰紡锛岃€孲ynchronized鍜孋AS鏄畠浠搴旂殑琛ㄧ幇褰㈠紡銆侰AS缂虹偣CAS鏈変粈涔堢己鐐瑰悧锛熶絾浠讳綍浜嬫儏閮芥湁涓や釜鏂归潰锛孋AS涔熶笉渚嬪銆傛帴涓嬫潵锛岃鎴戜滑鐪嬬湅CAS鐨勭己鐐广€侫BA闂CAS鏈€钁楀悕鐨勯棶棰樺氨鏄疉BA锛岄偅涔堜粈涔堟槸ABA鍛紵鎴戜滑鍋囪鍐呭瓨涓殑鍊兼槸A锛岃繖涓€肩殑鍙樺寲缁忓巻浜咥-->B-->A銆傛渶鍚庤繕鏄彲浠ュ姣旀鏌ョ殑銆傞€氳繃浜嗭紝浣嗘湰璐ㄤ笂鍐呭瓨涓殑鍊煎彂鐢熶簡鍙樺寲锛岃繖灏辨槸ABA闂銆備妇涓牀瀛愬惂銆傜嚎绋婣鍜岀嚎绋婤鍚屾椂鑾峰彇鍒拌淇敼鐨勫€糧銆傚綋绾跨▼A鍜岀嚎绋婤浣跨敤CAS鎿嶄綔鏃讹紝鍙傛暟鍐呭瓨涓殑鍊煎拰鏈熸湜鍊奸兘鏄痁锛汣PU璋冨害锛岀嚎绋婣鎴愬姛淇敼鍊糧涓篨锛涜繖鏃跺彟涓€涓嚎绋婥杩涙潵浜嗭紝浠栧緱鍒颁簡绾跨▼A淇敼鐨勫€糥銆傚綋绾跨▼C浣跨敤CAS鎿嶄綔鏃讹紝鍙傛暟鍐呭瓨涓殑鍊煎拰鏈熸湜鍊奸兘鏄疿锛汣PU璋冨害锛岀嚎绋婥鐨勬搷浣滃彲鑳芥瘮绾跨▼B濂斤紝绾跨▼C鍏堟搷浣滀慨鏀瑰€间粠X鍒癦锛涚粓浜庤疆鍒扮嚎绋婤浜嗭紝绾跨▼B鎿嶄綔淇敼Z涓篩锛屾搷浣滄垚鍔燂紱浣嗘槸涓棿鍊糧琚慨鏀逛簡锛岀嚎绋婤涓嶇煡閬擄紝杩樻槸鍌诲偦鐨勪慨鏀逛簡銆傛墍浠BA闂瀛樺湪涓€瀹氱殑椋庨櫓銆侫BA闂濡備綍瑙e喅锛屽彲浠ュ姞涓€涓増鏈彿锛圴ersion锛変綔涓烘瘮瀵规牎楠岀殑渚濇嵁锛屼篃灏辨槸璇翠笉浠呰姣斿唴瀛樹腑鐨勫€煎拰鏈熸湜鍊硷紝杩樿姣斿鐗堟湰鍙凤紝姣忔CAS鎿嶄綔鎴愬姛鍚庯紝鐗堟湰鍙?Version+1)銆傝繕鏄竴鏍风殑鏍楀瓙銆傜嚎绋婣鍜岀嚎绋婤鍚屾椂鑾峰彇鍒拌淇敼鐨勫€糧銆傚綋绾跨▼A鍜岀嚎绋婤浣跨敤CAS鎿嶄綔鏃讹紝鍙傛暟鍐呭瓨涓殑鍊煎拰鏈熸湜鍊奸兘鏄痁锛岀増鏈彿涔熸槸D锛汣PU璋冨害锛岀嚎绋婣鎴愬姛淇敼Z鍊间负X锛岀増鏈彿D+1淇敼涓篋1锛涜繖鏃跺€欏彟涓€涓嚎绋婥杩涙潵浜嗭紝浠栬幏鍙栧埌绾跨▼A淇敼鐨勫€糥锛屽綋绾跨▼C浣跨敤CAS鎿嶄綔鏃讹紝鍙傛暟鍐呭瓨涓殑鍊煎拰鏈熸湜鍊奸兘鏄疿锛岀増鏈彿鏄疍1锛汣PU璋冨害锛岀嚎绋婥鐨勬搷浣滃彲鑳芥瘮绾跨▼B濂斤紝绾跨▼C棣栧厛鎿嶄綔灏嗗€间粠X鍙樹负Z锛岀増鏈彿D1+1鍙樹负D2锛涚粓浜庤疆鍒扮嚎绋婤浜嗭紝绾跨▼B鐨勬搷浣滃皢Z鍙樹负Y锛屼絾鏄鏃讹紝鍥犱负姝ゆ椂鑾峰彇鐨勭増鏈彿D涓嶇瓑浜庡綋鍓嶇殑鐗堟湰鍙稤2锛屾墍浠ユ搷浣滃け璐ャ€傚惊鐜鏁板お闀裤€傚鏋滄湁澶ч噺绾跨▼浠庣嚎绋婣銆丅銆丆銆丏鈥︹€﹀埌绾跨▼Z锛岄兘瀵瑰悓涓€涓叡浜彉閲忚繘琛屾搷浣滐紝鍚屾椂鍙湁涓€涓嚎绋嬪彲浠ュ畬鎴愭搷浣滐紝閭d箞濡傛灉鍏朵粬绾跨▼澶辫触锛岀户缁皾璇曘€傞暱鏃堕棿鐨凜AS閲嶈瘯鎿嶄綔浼氱粰CPU甯︽潵姣旇緝澶х殑寮€閿€銆傛墍浠ユ棆杞殑娆℃暟鏄湁闄愮殑銆傛瘮濡傚崌绾ynchronized閿佹椂锛屽鏋滃娆″皾璇旵AS锛堣嚜鏃嬶級閮芥病鏈夋嬁鍒伴攣锛屽氨浼氬崌绾т负閲嶉噺绾ч攣銆侰AS鍦↗ava涓殑浣撶幇(1.8)AtomicXXXCAS鍦↗ava涓渶钁楀悕鐨勪綋鐜版槸java.util.concurrent.atomic鍖呬笅浠tomic寮€澶寸殑绫汇€傝繖閲屾垜浠妇涓牀瀛愷煂颁娇鐢ˋtomicLong銆備互鏈€甯哥敤鐨刬ncrementAndGet()涓哄垏鍏ョ偣锛屾垜浠潵鐪嬬湅瀹冩槸濡備綍瀹炵幇鐨勩€俻ublicclassAtomicLongextendsNumberimplementsjava.io.Serializable{privatestaticfinalUnsafeunsafe=Unsafe.getUnsafe();绉佹湁闈欐€佹渶缁堥暱鍊煎亸绉婚噺锛泂tatic{try{valueOffset=unsafe.objectFieldOffset(AtomicLong.class.getDeclared"Field);}catch(Exceptionex){thrownewError(ex);}}privatevolatilelongvalue;publicfinallongincrementAndGet(){杩斿洖涓嶅畨鍏ㄣ€俫etAndAddLong(this,valueOffset,1L)+1L;}}浠庢簮鐮佸彲浠ョ湅鍑猴紝incrementAndGet璋冪敤浜哢nsafe绫荤殑getAndAddLong鏂规硶锛屼紶鍏ヤ簡涓変釜鍙傛暟锛宼his锛堝綋鍓嶅璞★級锛寁alueOffset锛?L銆傝繖涓獀alueOffset鏄彉閲忓€煎湪鍐呭瓨涓殑鍋忕Щ鍦板潃锛屽€肩殑鑾峰彇鏄湪闈欐€佷唬鐮佸潡涓畬鎴愮殑锛寀nsafe鏄€氳繃鍋忕Щ鍦板潃鑾峰彇鏁版嵁鐨勫師濮嬪€硷紱璇ュ€兼槸volatile鐨勶紝灏辨槸涓轰簡淇濊瘉璇ュ€糾ore涓や釜绾跨▼涔嬮棿鐨勮鏁版槸涓€鏍风殑锛涜繖閲屾渶鍚庡姞涓?L鏄洜涓篣nsafe鐨刧etAndAddLong鏂规硶杩斿洖鏃у€艰涔夋槸i++锛涜€宨ncrementAndGet鐨勮涔夋槸++i锛岀湅鏉ラ棶棰樼殑鍏抽敭鍦ㄤ簬涓嶅畨鍏ㄧ被銆傚厛绠€鍗曚粙缁嶄笅Unsafe绫汇€侸ava涓嶈兘鐩存帴璁块棶鎿嶄綔绯荤粺锛岃€屾槸閫氳繃native鏂规硶銆俇nsafe绫诲湪Java绾у埆鎻愪緵姝ょ被鏀寔銆俷ative鏂规硶澶氭槸璋冪敤C鎴朇++浠g爜锛岀劧鍚嶤鎴朇++浠g爜璋冪敤姹囩紪璇█鐢熸垚涓€浜汣PU鎸囦护杩涜杩愯銆俻ublicfinalclassUnsafe{publicfinallonggetAndAddLong(Objectvar1,longvar2,longvar4){longvar6;鍋歿var6=this.getLongVolatile(var1,var2);}while(!this.compareAndSwapLong(var1,var2,var6,var6+var4));杩斿洖var6锛泒publicfinalnativebooleancompareAndSwapLong(Objectvar1,longvar2,longvar4,longvar6);}getAndAddLong鏂规硶棣栧厛鑾峰彇鏃у€硷紙鏈熸湜鍊硷級銆傜劧鍚庤皟鐢╪ative鏂规硶compareAndSwapLong锛坈as鎿嶄綔锛夛紝浼犲叆鍥涗釜鍙傛暟锛氬綋鍓嶅璞★紝value鍦ㄥ唴瀛樹腑鐨勫亸绉诲湴鍧€锛屾湡鏈涘€硷紝鏂板€笺€傛垚鍔熸椂閫€鍑哄惊鐜苟杩斿洖鏃у€笺€傝繖閲岀殑native鏂规硶compareAndSwapLong鏄皟鐢–鎴朇++鐨勪唬鐮侊紝鏈€缁堢敓鎴愪竴鏉PU鎸囦护cmpxchg锛屼繚璇佸叾鎿嶄綔鐨勫師瀛愭€с€傚垰鎵嶆垜浠彁鍒癈AS浼氶亣鍒癆BA闂锛孞ava涔熸彁渚涗簡鐩稿簲鐨勭被AtomicStampedReference鍜孉tomicMarkableReference浣滀负瑙e喅鏂规銆傛湰璐ㄤ笂涔熸槸閫氳繃鐗堟湰鍙枫€傛湁鍏磋叮鐨勫皬浼欎即鍙互浠庡弬鑰冮摼鎺eadJavaConcurrency鍜屽皬瀹禞ava涓粩缁嗛槄璇诲畠鐨勭敤娉曞拰鍘熺悊銆侺ongAdderLongAdder鏄湪JDK1.8涓帹鍑虹殑銆備笅闈㈢殑JavaDoc鏄叾鍔熻兘鎻忚堪鍜孉tomicLong鐨勫姣斻€?
褰撳涓嚎绋嬫洿鏂扮敤浜庢敹闆嗙粺璁℃暟鎹瓑鐩殑鐨勫叕鍏辨€诲拰鏃讹紝姝ょ被閫氬父浼樹簬{@linkAtomicLong}锛岃€屼笉鏄敤浜庣粏绮掑害鍚屾*鎺у埗銆傚湪浣庢洿鏂扮珵浜変笅锛岃繖涓や釜绫诲叿鏈夌浉浼肩殑*鐗规€с€備絾鍦ㄩ珮绔炰簤涓嬶紝*姝ょ被鐨勯鏈熷悶鍚愰噺鏄庢樉鏇撮珮锛屼絾浠d环鏄洿楂樼殑绌洪棿*娑堣€椼€備粠鎻忚堪涓彲浠ョ湅鍑猴紝LongAdder鏇村鐨勬槸鐢ㄤ簬鏀堕泦缁熻鏁版嵁锛岃€屼笉鏄疐ine-grained鍚屾鎺у埗銆侺ongAdder鍜孉tomicLong鍦ㄤ綆骞跺彂鏃舵病鏈夊お澶у尯鍒紝浣嗘槸鍦ㄩ珮骞跺彂鏃讹紝LongAdder閫氳繃鐗虹壊绌洪棿鏉ユ彁楂樺悶鍚愰噺銆傜畝鍗曚粙缁嶄竴涓婰ongAdder鐨勮璁℃€濊矾銆侺ongAdder浼氬皢鍊兼斁鍏ヤ竴涓暟缁勪腑浣滀负鏁扮粍鍏冪礌鐨勫€硷紝鐒跺悗灏嗗苟鍙戠嚎绋嬪垎閰嶇粰鍏朵腑涓€涓€艰繘琛岃绠楋紝鏈€鍚庡皢杩欎簺鍊肩浉鍔犲緱鍒版渶缁堝€笺€傚浘鐗囨憳鑷猍Xiaojiajava]AtomicLong鍙互涓㈠純锛岃鏀圭敤LongAdder锛堟垨浣跨敤LongAccumulator锛夈€傛帴涓嬫潵锛岃鎴戜滑鐪嬩竴涓嬫簮浠g爜銆傝鎴戜滑浠ュ閲忎负璧风偣銆俻ublicclassLongAdderextendsStriped64implementsSerializable{...publicvoidincrement(){add(1L);}publicvoidadd(longx){Cell[]as;闀縝,v;璇犻噴绫?缁嗚優涓€涓紱if((as=cells)!=null||!casBase(b=base,b+x)){booleanuncontended=true;if(as==null||(m=as.length-1)<0||(a=as[getProbe()&m])==null||!(uncontended=a.cas(v=a.鍊硷紝v+x)))longAccumulate(x,null,uncontended);}}}abstractclassStriped64extendsNumber{/***鍩哄€硷紝涓昏鍦ㄦ病鏈変簤鐢ㄦ椂浣跨敤锛屼絾涔熶綔涓鸿〃鍒濆鍖栫珵璧涙湡闂寸殑鍥為€€銆傞€氳繃CAS鏇存柊銆?/transientvolatilelongbase;@sun.misc.ContendedstaticfinalclassCell{volatilelongvalue;鍗曞厓鏍硷紙闀縳锛墈鍊?x锛泒finalbooleancas(longcmp,longval){杩斿洖UNSAFE.compareAndSwapLong(this,valueOffset,cmp,val);}//涓嶅畨鍏ㄦ満鍒秔rivatestaticfinalsun.misc.UnsafeUNSAFE;绉佹湁闈欐€佹渶缁堥暱鍊煎亸绉婚噺锛涢潤鎬亄灏濊瘯{涓嶅畨鍏?sun.misc.Unsafe.getUnsafe();绫??>ak=Cell.class;valueOffset=UNSAFE.objectFieldOffset(ak.getDeclaredField("value"));}catch(Exceptione){thrownewError(e);}}}}浠庝唬鐮佺9琛屽彲浠ョ湅鍑篊ell鏁扮粍宸茬粡杩涜浜嗙┖鎿嶄綔锛岃鏄庝竴寮€濮嬫暟缁勬病鏈夊垵濮嬪寲锛岀劧鍚巆asBase(b=base,b+x)杩涜cas鎿嶄綔锛岃繖涓猙ase鐨勫€兼槸鍦↙ongAdder鐖剁被Striped64涓畾涔夌殑锛屼粠娉ㄩ噴淇℃伅鏉ョ湅锛屽氨鏄痓ase鍊笺€傚綋绾跨▼娌℃湁浜夌敤鏃朵娇鐢ㄣ€傜湅鍒拌繖閲岋紝鎴戜滑鍙互寰楀嚭涓€涓粨璁猴細LongAdder涓嶄細鍦ㄤ竴寮€濮嬬嚎绋嬬珵浜夋槸鏃犵珵浜夌殑鎯呭喌涓嬬洿鎺ヤ娇鐢–ell鏁扮粍锛岃€屾槸浣跨敤volatile鍩哄彉閲忔潵瀛樺偍鏃犵珵浜夋潵琛ㄧず绔炰簤鏄惁婵€鐑堛€傛帴涓嬫潵鐨勪唬鐮佹槸褰撳墠闈㈢殑鏉′欢casBase琛ㄧず绔炰簤澶辫触鏃躲€備笅闈㈢殑鍒ゆ柇鏉′欢鏄珵浜夊垰鍒氬彂鐢燂紝Cell鏁扮粍杩樻病鏈夊垱寤烘垨鑰呯嚎绋嬫墍鍦ㄧ殑Cell鐨刢as鎿嶄綔澶辫触锛岃〃鏄庡瓨鍦ㄧ珵浜夈€傞潪甯告縺鐑堬紝杩欐椂鍊欓渶瑕佽皟鐢╨ongAccumulate鏂规硶鏉ュ垱寤哄拰鎵╁睍Cell鏁扮粍銆傛渶鍚庯紝褰撻渶瑕佸彇鍊肩殑鏃跺€欙紝闇€瑕佽皟鐢╯um鏂规硶锛屼篃灏辨槸灏咰ell鏁扮粍鐨勫€肩浉鍔犲緱鍒版渶缁堢殑缁撴灉銆俻ublicclassLongAdderextendsStriped64implementsSerializable{publiclongsum(){Cell[]as=cells;缁嗚優涓€涓?闀挎€诲拰=鍩烘暟锛沬f(as!=null){for(inti=0;i