1. 程式人生 > >JAVA CAS初識

JAVA CAS初識

多執行緒併發協同通訊一直都是不可避之的話題,尤其是現代多核處理器的發展更推動了關於這方面的研究。

在JAVA領域,JDK 5之前是靠synchronized關鍵字保證同步的,而這會導致產生比較重量級的鎖,通常會導致執行緒阻塞、等待、喚醒。如果執行緒的這種狀態切換比較頻繁可能會加重CPU的負擔,這樣可能會阻礙真正有意義的處理。

而CAS這種演算法的出現可以避免這些,CAS是從硬體層面作一些變數操作的原子性強控,這些並不會導致JAVA執行緒的阻塞,你也可以理解它其實也有一把鎖,就是在比對更新的時候鎖住,但是這把鎖非常輕量化。
關於CAS的一些詳細原理、發展史、以及詳細說明,這裡不作解釋,不懂可以度娘。

今天只是初識了下JAVA的AtomicReference
以下是程式碼截圖,同時附上了相關理解說明:

package test.atomic.reference;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;

/**
 *
 * 該用例意在說明用CAS原理基於一個預期的值作更新時(更新後的值與預期值不一樣),
 * 我們可以保證從讀取判斷到更新值這一個過程是原子方式進行操作的,
 * 所以在多執行緒併發的時候只會有一個成功,因為後面的執行緒在作CAS時會發現預期值已經改變
 * 這可以避免對同一個域進行多次寫操作
 *
 * 注意點:多執行緒併發做該操作只會有一個成功
 *
 */
public class CompareAndSetTest { private static AtomicReference<Object> obj = new AtomicReference<>(); public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(100); for (int i = 0; i < 100000; i++) { executorService.submit(new
ObjReferenceHandler()); } executorService.shutdown(); } public static void printWrappedInfo(Object info, String type) { long id = Thread.currentThread().getId(); System.out.println(id + ": [" + type + "] --> " + info); } public static void printBeforeObj(Object info) { printWrappedInfo(info, "before"); } public static void printAfterObj(Object info) { printWrappedInfo(info, "after"); } public static void printCASResult(Object info) { printWrappedInfo(info, "CAS"); } static class ObjReferenceHandler implements Runnable { @Override public void run() { Object beforeObj = new Object(); printBeforeObj(beforeObj); boolean b = obj.compareAndSet(null, beforeObj); printCASResult(b); Object afterObj = obj.get(); printAfterObj(afterObj); } } }
package test.atomic.reference;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;

/**
 *
 * 該用例意在用CAS原理基於當前值作更新,
 * 我們可以保證的是更新完成後,所作的更新是基於一個當前引用值作更新,而不是基於一個過期的引用值
 * 事實上我們並不關心當前引用值的具體狀態,我們能保證的是:併發更新時,從讀取、到經過運算、再到更新引用變數,這個流程最終會通過CAS,
 * 換名話說我們並不能保證這個流程一直是原子性的,但是終有一次通過了CAS,它一定是原子性的,而此時會中止嘗試,因為已經成功以原子方式更新了引用值
 *
 * 總的來說所有成功的操作才是有意義的,所有成功的操作在時間分片上一定是互不交叉的,最終保證了整體執行完成後,在最終效果上是同步的
 *
 * 注意點:對當前值不作任何預測,只是作CAS直到成功
 *
 */
public class UpdateAndGetTest {

    private static final AtomicReference<Integer> atomicInteger = new AtomicReference<>();


    static {
        atomicInteger.set(0);
    }

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 100; i++) {
            executorService.submit(new PlusNumber());
        }
        executorService.shutdown();
    }

    private static class PlusNumber implements Runnable {
        @Override
        public void run() {
            System.out.println(atomicInteger.updateAndGet(i -> i + 1));
        }
    }



}

相關推薦

JAVA CAS初識

多執行緒併發協同通訊一直都是不可避之的話題,尤其是現代多核處理器的發展更推動了關於這方面的研究。 在JAVA領域,JDK 5之前是靠synchronized關鍵字保證同步的,而這會導致產生比較重量級的鎖,通常會導致執行緒阻塞、等待、喚醒。如果執行緒的這種狀態切

Java CAS原理

沒有 機器 存在 dcom false height ret 一致性 con java.util.concurrent包完全建立在CAS之上的,沒有CAS就不會有此包。可見CAS的重要性。 CAS CAS:Compare and Swap, 翻譯成比較並交換。

Java CAS簡析

tun 級別 integer 樂觀鎖 操作 func pri off title 什麽是CAS CAS:Compare and Swap,它是一種原子操作,什麽是原子操作,可以在多線程編程中實現數據交換而不被打斷。是用來更新變量的,當多個線程使用CAS來更新變量時,只有一個

Java CAS ABA問題發生的場景分析

進行 有一個 pri 出棧 .com package pan compare 變量   提到了CAS操作存在問題,就是在CAS之前A變成B又變回A,CAS還是能夠設置成功的,什麽場景下會出現這個問題呢?查了一些資料,發現在下面的兩種情況下會出現ABA問題。   1.A最開始

java開發初識

虛擬機 代碼 避免 jvm java 使用 數據 spa path環境變量 jdk目錄相關介紹: bin:存放的是java的相關開發工具 db:顧名思義jre附帶的輕量級數據庫 include:存放的是調用系統資源的接口文件

Java CAS總結

發生 其他 text 修改 分析 引用 sso 允許 什麽 文章目錄 1、 CPU指令對CAS的支持(CPU的cas指令是原子的) 或許我們可能會有這樣的疑問,假設存在多個線程執行CAS操作並且CAS的步驟很多,有沒有可能在判斷V和E相同後,正要賦值時,

JAVA CAS

控制 comment 種類 簡單 功能 The ESS ... 發展 原文鏈接:https://blog.csdn.net/mmoren/article/details/79185862 本篇的思路是先闡明無鎖執行者CAS的核心算法原理然後分析Java執行CAS的實踐者U

JAVA IO初識

看了別個的帖子,自己精簡的記一下。以備檢視 原帖 http://blog.csdn.net/zxman660/article/details/7875799 首先,在JAVA API中,可以從其中讀入一個字元序列的物件稱作輸入流,而可以從中寫入一個字元序列的物件稱作輸出流。

java cas client 配置引數說明

(CAS 一搜全是配置,確沒找到一個每個配置解釋具體含義的,自己寫一篇,希望能幫到看到這一篇部落格的你) AuthenticationFilter 需要配兩個引數: 一 casServerLoginUrl   cas 認證(使用者輸入使用者名稱密碼)的URL

Java集合初識

什麼是集合? Java集合類是一種特別有用的工具類,可用於儲存數量不等的物件,並可以實現常用的資料結構,如棧、佇列等。除此之外,集合還可用於儲存具有對映關係的關聯陣列。 集合與陣列的區別 陣列的長度是固定的;集合的長度是可變的。 陣列可以儲存基本資料型別,也可以儲存引用

面試問題(java cas有什麼優點和問題)

java.util.concurrent包完全建立在CAS之上的,沒有CAS就不會有此包。可見CAS的重要性。 CAS CAS:Compare and Swap, 翻譯成比較並交換。  java.util.concurrent包中藉助CAS實現了區別於synchro

JAVA CAS原理深度分析

CAS CAS:Compare and Swap, 翻譯成比較並交換。  java.util.concurrent包中藉助CAS實現了區別於synchronouse同步鎖的一種樂觀鎖。 本文先從CAS的應用說起,再深入原理解析。 CAS應用 CAS有3個運算元,記憶

Java CAS(Compare And Swap)的一點理解

CAS: Compare And Swap, 即比較和替換。思想: CAS的比較、替換操作是非阻塞操作, 它有3個引數分別為記憶體值、預期值和更新值。 當記憶體值和預期值匹配時則更新, 不匹配時直接返回。PS: CAS比synchronized效率要好,  因為CAS是c語言

Java CAS 和 synchronized 和 Lock

CAS 機制 適用場景:樂觀認為併發不高,不需要阻塞,可以不上鎖。 特點:不斷比較更新,直到成功。 缺點:高併發cpu壓力大;ABA問題。 ABA問題: CAS機制生效的前提是,取出記憶體中

JAVA爬蟲初識之模擬登入

在設計一個爬蟲的時候,在第一步對網站的大概瀏覽瞭解情況是會發現有些網站在訪問之前是需要登入的,否則是無法訪問到有我們需要的資料的子頁面的,這個時候就要在之前的基礎上增加一個模擬登入的步驟。 其實模擬登入的步驟跟之前所說的httpclient基本是一樣的,只不過

Java CAS自旋鎖

悲觀者與樂觀者的做事方式完全不一樣,悲觀者的人生觀是一件事情我必須要百分之百完全控制才會去做,否則就認為這件事情一定會出問題;而樂觀者的人生觀則相反,凡事不管最終結果如何,他都會先嚐試去做,大不了最後不成功。這就是悲觀鎖與樂觀鎖的區別,悲觀鎖會把整個物件加鎖佔為自有後才去做操作,樂觀鎖不獲取鎖直接做操作,然

JAVA CAS原理深度分析 concurrent實現

java.util.concurrent包完全建立在CAS之上的,沒有CAS就不會有此包。可見CAS的重要性。 CAS CAS:Compare and Swap, 翻譯成比較並交換。  java.util.concurrent包中藉助CAS實現了區別於synchronou

Java cas-client-3.1.3 設定不攔截失效解決辦法

1、今天在和客戶聯調時發現個問題,就是cas的不攔截失效,所有的方法都被攔截了,原因就是 web.xml配置如下: 如上可以看出,cas攔截了所有的路徑,不攔截的配置並沒有起到作用。 2、解決辦法:這樣的問題首先要搞懂原理,底層程式碼的編寫,首先準備一個反編譯工具Java Deco

Java cas-clienct-3.1.3 配置

本人在使用cas單點登陸的時候,使用的是3.4.1,因為在maven倉庫沒有下載到3.1.3的jar。由於服務端使用的是3.1.3的jar ,如果不一致,單點登入的登出操作就不能正常使用。 不過這裡面有無數個坑,首先,下載3.1.3jar包,不要直接lib引入,不然tomcat啟動的時候會一直報

JAVA爬蟲初識之HTTP通訊機制

最近接觸爬蟲相關知識,將學習和網上了解到的一些東西記錄下來,以便以後需要。(刪除重新發一次) HTTP通訊機制 HTTP(HyperText Transfer Protocol)是一套計算機通過網路進行通訊的規則。HTTP是一種無狀態的協議(Web瀏覽器和W