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類只能保證在自增或者自減的情況下保證執行緒安全
相關推薦
AtomicInteger類和int原生型別自增鮮明的對比
AtomicInteger這個類的存在是為了滿足在高併發的情況下,原生的整形數值自增執行緒不安全的問題。比如說 int i = 0 ; i++; 上面的寫法是執行緒不安全的。 有的人可能會說了,可以使用synchronized關鍵字啊。
java:String類和int型別相互轉換
public class Demo1_Integer { public static void main(String[] args) { // TODO Auto-generated meth
Java 自增(++) 和 C語言中自增的區別
%d 區別 但是 [] .cn cnblogs 微軟雅黑 自增 華麗 在Java、c語言等高級語言中自增和自減的作用基本一致,都是變量自身加一或減一。下面我只對自增進行說明,自減是類似的。 自增運算符(++),有兩種書寫形式,一個是在變量前: ++ num; 另一種
[Swift]ASCII值的獲取和轉換:擴充套件Character類和Int類
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
使用UUID和int自增主鍵的區別
知其然,知其所以然。在看到生成UUID的程式碼,後帶給我的百度結合自己的經驗再寫下來的區別 一.UUID做主鍵: 優點: 1.保證資料在表和庫都是獨立的,有利於後續的分庫 2.合併表的時候主鍵不會重複 3.有大量資料的時候主鍵不會像int那樣越界 4.有利於處理分散式儲存的資料表
Mybatis需要返回的資料引數中在資料表中沒有對應的欄位,自定義實體類和resultmap作為返回值型別
自定義實體類:因為需要做相關記錄的統計,而表中沒有統計欄位 public class TrafficJeevesDistrictCount { //施工top5+1 按區域 private String districtInfo; private
java中的BigDecimal和String的相互轉換,int和String的型別轉換,Integer類和String相互轉換
一: /*由數字字串構造BigDecimal的方法 *設定BigDecimal的小數位數的方法 */ 注:BigDecimal在資料庫中存的是number型別。 import java.math.BigDecimal; //數字字串 String StrBd="1048576.1024"; /
Integer和int的區別,包裝類,基本資料型別,區別
int 是基本資料型別。Integer是其包裝類,注意是一個類。https://zhidao.baidu.com/question/322364721.html ----包裝類,和資料型別,使用上,有什麼區別?下面舉個例子:int test0;TestBean test2;
封裝類和非封裝類比較相同不int和Integer
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,