1. 程式人生 > >AtomicInteger類和int原生型別自增鮮明的對比

AtomicInteger類和int原生型別自增鮮明的對比

AtomicInteger這個類的存在是為了滿足在高併發的情況下,原生的整形數值自增執行緒不安全的問題。比如說

    int i = 0 ;
    i++;

上面的寫法是執行緒不安全的。
有的人可能會說了,可以使用synchronized關鍵字啊。
但是這裡筆者要說的是,使用了synchronized去做同步的話系統的效能將會大大下降。
所以此時AtomicInteger這個類的使用就可以滿足上述的情況。
當我們統計一個頁面的瀏覽量的時候,可以使用該類來統計,而不再使用++運算子。

但是在使用的過程中,筆者發現,使用++運算子和AtomicInteger的結果都是對的。。。

結果有點暈了,難道結論是錯的麼?當然不是了。
注意這個類使用的情況下是在高併發量的情況下。不是同時啟10個20個執行緒,而是成千上萬個執行緒。

我們先看看AtomicInteger類起作用的程式碼

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

public class AtomicIntegerTest {
    public static final AtomicInteger atomicInteger = new
AtomicInteger(0); public static void main(String[] args) throws InterruptedException { atomicIntegerTest(); Thread.sleep(3000); System.out.println("最終結果是" + atomicInteger.get()); } private static void atomicIntegerTest() { ExecutorService executorService = Executors.newFixedThreadPool(10000
); for (int i = 0; i < 10000; i++) { executorService.execute(() -> { for (int j = 0; j < 4; j++) { System.out.println(atomicInteger.getAndIncrement()); } }); } executorService.shutdown(); } }

列印的結果是4萬
這裡寫圖片描述
再看看++操作符

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

public class IntValueIncrementTest {

    public static int value = 0;

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(10000);
        for (int i = 0; i < 10000; i++) {
            executorService.execute(() -> {
                for (int j = 0; j < 4; j++) {
                    System.out.println(value++);
                }
            });
        }
        executorService.shutdown();
        Thread.sleep(3000);
        System.out.println("最終結果是" + value);
    }
}

這裡寫圖片描述
我們可以看到結果是39972,顯然結果丟失了一些。
所以在高併發的情況下應當使用AtomicInteger類

當我們在併發情況下,但是併發量又不是那麼大的時候,
我們將上述的程式碼改掉,改為同時只有10個執行緒在修改數值。
我們貼程式碼

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

public class AtomicIntegerTest {
    public static final AtomicInteger atomicInteger = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        atomicIntegerTest();

        Thread.sleep(3000);
        System.out.println("最終結果是" + atomicInteger.get());
    }

    private  static void atomicIntegerTest() {
        ExecutorService executorService = Executors.newFixedThreadPool(10000);
        for (int i = 0; i < 10; i++) {
            executorService.execute(() -> {
                for (int j = 0; j < 4; j++) {
                    System.out.println(atomicInteger.getAndIncrement());
                }
            });
        }
        executorService.shutdown();
    }
}

這裡寫圖片描述
執行的結果是40

再貼10個執行緒的併發量的情形。

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

public class IntValueIncrementTest {

    public static int value = 0;

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(10000);
        for (int i = 0; i < 10; i++) {
            executorService.execute(() -> {
                for (int j = 0; j < 4; j++) {
                    System.out.println(value++);
                }
            });
        }
        executorService.shutdown();
        Thread.sleep(3000);
        System.out.println("最終結果是" + value);
    }
}

這裡寫圖片描述
發現此時的結果也是40。
所以這就給人一種假象:
1)AtomicInteger類不起作用.
2)i++或者++i是執行緒安全的
其實上面兩點觀念都是錯誤的。是因為併發量不夠高而已
但是需要注意的是AtomicInteger類只能保證在自增或者自減的情況下保證執行緒安全

相關推薦

AtomicIntegerint原生型別鮮明對比

AtomicInteger這個類的存在是為了滿足在高併發的情況下,原生的整形數值自增執行緒不安全的問題。比如說 int i = 0 ; i++; 上面的寫法是執行緒不安全的。 有的人可能會說了,可以使用synchronized關鍵字啊。

java:Stringint型別相互轉換

public class Demo1_Integer { public static void main(String[] args) { // TODO Auto-generated meth

Java (++) C語言中的區別

%d 區別 但是 [] .cn cnblogs 微軟雅黑 自增 華麗 在Java、c語言等高級語言中自增和自減的作用基本一致,都是變量自身加一或減一。下面我只對自增進行說明,自減是類似的。 自增運算符(++),有兩種書寫形式,一個是在變量前: ++ num; 另一種

[Swift]ASCII值的獲取轉換:擴充套件CharacterInt

Character轉ASCII整數值: 1 //Character擴充套件方法 2 extension Character 3 { 4 //屬性:ASCII整數值(定義小寫為整數值) 5 var ascii: Int { 6 get {

獲取mysql id mysql 下一個id的方法

mysql獲取表中自增id的方法: 1. 使用 select MAX(id) from tablename; 獲取的是表中最大的id;順序執行  insert ---> delete 插入的資料----> select MAX(id) from tablenam

Java中基本資料型別與對應的包裝引用資料型別

基本資料型別變數儲存的是值,引用型別儲存的是物件的引用(物件的地址)。 基本資料型別不具有物件的特性,當有些地方必須要使用物件的時候,例如集合類(List,Set等),基本資料型別就不能使用了,所以Java提供了包裝類。基本資料型別可以進行加減乘除等運算,而包裝類提供了很多

String基本資料型別包裝

-----------android培訓、java培訓、java學習型技術部落格、期待與您交流!------------  第一講     String類 一、概述         String是字

自制工具:CSV程式碼生成器:自動生成CSV檔案對應的C++實體欄位型別解析程式碼

更有開發效率地使用CSV檔案 為了更有效率地使用CSV檔案,我製作了一個工具:Code程式碼生成器。 這個工具可以對CSV檔案進行簡單地配置,自動生成這個CSV檔案對應的C++資料結構和欄位型別解析函式程式碼。 工程專案只要加入這些自動生成的程式碼,就可以更方便地使

mysql 批量更新數據庫主鍵為int,bigint 型,字段為

span pre and style cat pri odi rem script select table_name, concat(‘alter table `‘,table_name,‘` MODIFY ‘, column_name, ‘ ‘, da

使用UUIDint主鍵的區別

知其然,知其所以然。在看到生成UUID的程式碼,後帶給我的百度結合自己的經驗再寫下來的區別 一.UUID做主鍵: 優點: 1.保證資料在表和庫都是獨立的,有利於後續的分庫 2.合併表的時候主鍵不會重複 3.有大量資料的時候主鍵不會像int那樣越界 4.有利於處理分散式儲存的資料表   

Mybatis需要返回的資料引數中在資料表中沒有對應的欄位,定義實體resultmap作為返回值型別

自定義實體類:因為需要做相關記錄的統計,而表中沒有統計欄位 public class TrafficJeevesDistrictCount { //施工top5+1 按區域 private String districtInfo; private

java中的BigDecimalString的相互轉換,intString的型別轉換,IntegerString相互轉換

一: /*由數字字串構造BigDecimal的方法 *設定BigDecimal的小數位數的方法 */ 注:BigDecimal在資料庫中存的是number型別。 import java.math.BigDecimal; //數字字串 String StrBd="1048576.1024"; /

Integerint的區別,包裝,基本資料型別,區別

int 是基本資料型別。Integer是其包裝類,注意是一個類。https://zhidao.baidu.com/question/322364721.html ----包裝類,和資料型別,使用上,有什麼區別?下面舉個例子:int test0;TestBean test2;

封裝非封裝類比較相同不intInteger

com margin idt val image 相同 -1 img wid A.所有和int(非封裝類比較的,只要數值相同就行) B.io3由valueof弄出來的,所以和io1相同 C.io4是new出來的,所以地址不一樣,就不相同 D.和A相同封裝類和非封裝類比較相

MySQL 使用ID主鍵UUID 作為主鍵的優劣比較具體過程(從百萬到千萬表記錄測試)

popu tis pack 方案 表數據 lock 進行 args ios ?測試緣由? 一個開發同事做了一個框架。裏面主鍵是uuid。我跟他建議說mysql不要用uuid用自增主鍵,自增主鍵效率高,他說不一定高,我說inn

MyBaits基本操作,為什麽session.commit()可以引起事物提交?ResultMap結果映射,執行添加後返回列的值,多條件查詢,智能標簽,工具

info log list image mit fault 類型 工具類 自增列 1.為什麽session.commit()可以引起事務的提交? 首先打開commit()源碼,ctrl+H打開它的實現類DefaultSession,找到它的commit方法 ctrl+左鍵

Java運算符使用總結(重點:減、位運算邏輯運算)

運算 計算器 可讀性 過多 移位運算 style avi 學會 new Java運算符共包括這幾種:算術運算符、比較運算符、位運算符、邏輯運算符、賦值運算符和其他運算符。(該圖來自網絡) 簡單的運算符,就不過多介紹使用了,可自行測試。關於賦值運算,可以結合算術運

減 i++ ++i的區別

post 宋體 font clas style span 與運算 rom ++ ◆在不參與運算的情況下,i++和++i都是在變量的基礎加1 ◆在參與運算的情況下 Var i=123; Var j=i++; 先將i的值123賦值給j,之後再自增 j的值為123 i

對象的刪改查

AI like wan spa ini python腳本 方法 一個 pri 最近寫一個簡單的python腳本,延遲了半個月的進度 接下來學習面向對象了 # 類的增刪改查 class Dog: def __init__(self,name,age,color)

【mybatis】mybatis中insert 主鍵的插入情況【mysql】

pro SQ class TE IV rop generate mys bat 主鍵不自增:返回值是插入的條數 <insert id="add" parameterType="EStudent"> insert into TStudent(name,