Java併發控制synchronized與AtomicInteger類
我們先通過一個簡單的例子模擬下多執行緒併發計數,程式如下
public class ShareData { public static int count=0; public static void main(String[] args){ final ShareData data = new ShareData(); for(int i=0;i<10;i++){ new Thread( new Runnable(){ public void run(){ try{ Thread.sleep(1); }catch(InterruptedException e){ e.printStackTrace(); } for(int j=0;j<100;j++){ data.addCount(); } System.out.print(count+" "); } } ).start(); } try{ Thread.sleep(3000); }catch(InterruptedException e){ e.printStackTrace(); } System.out.print("count="+count); } public void addCount(){ count++; } }
程式啟動了十個執行緒,每個執行緒計100次數,操作的都是count這個變數,最後在等待3秒(所有執行緒均執行結束後)輸出此時的count值,每次執行後的輸出結果都不一定一樣,但是一般count小於1000,結果如下:
100 224 373 473 373 255 823 791 691 591 count=823
344 566 366 299 299 466 366 669 695 769 count=769
400 400 400 500 400 615 913 813 713 713 count=913
我們將addCount()方法加上synchronized關鍵詞修飾下,讓它實現執行緒安全,
public synchronized void addCount(){ count++; }
再執行,結果如下:
200 200 411 677 774 864 1000 666 1000 891 count=1000
423 909 1000 428 802 512 691 706 512 914 count=1000
300 500 500 300 300 712 809 850 949 1000 count=1000
此時可以看出最終count的數值都會精確的是1000,講完了synchronized之後我們再來看下AtomicInteger類
AtomicInteger類可以用原子方式更新的
int 值,主要用於在高併發環境下的高效程式處理,使用非阻塞演算法來實現併發控制,它的方法有
這裡我們依然用上面的程式做例子,使用AtomicInteger類來替代synchronized方式,程式碼如下://獲取當前的值 public final int get() //取當前的值,並設定新的值 public final int getAndSet(int newValue) //獲取當前的值,並自增 public final int getAndIncrement() //獲取當前的值,並自減 public final int getAndDecrement() //獲取當前的值,並加上預期的值 public final int getAndAdd(int delta)
package concurrent;
import java.util.concurrent.atomic.AtomicInteger;
public class ShareData_AtomicInteger {
static AtomicInteger count = new AtomicInteger(0);
public static void main(String[] args){
final ShareData_AtomicInteger data = new ShareData_AtomicInteger();
for(int i=0;i<10;i++){
new Thread(
new Runnable(){
public void run(){
try{
Thread.sleep(1);
}catch(InterruptedException e){
e.printStackTrace();
}
for(int j=0;j<100;j++){
data.addCount();
}
System.out.print(count.get()+" ");
}
}
).start();
}
try{
Thread.sleep(3000);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.print("count="+count.get());
}
public void addCount(){
count.getAndIncrement();
}
}
執行結果如下:
495 528 604 504 987 657 741 682 1000 925 count=1000
500 500 984 823 499 733 500 495 601 1000 count=1000
409 409 436 409 700 587 600 872 988 1000 count=1000
至此結束,AtomicInteger只是concurrent下的一個整數原子操作類,該包下還有很多其他關於執行緒鎖同步的機制,有興趣的同學可以自行搜尋下相關資料~謝謝
相關推薦
Java併發控制synchronized與AtomicInteger類
眾所周知,在Java多執行緒程式設計中,一個非常重要的方面就是執行緒的同步問題。關於執行緒的同步,最常用的解決方法就是使用synchronized關鍵字,但是如果使用場景只用在控制一個計數的整型變數時
java併發之----synchronized與ReenTrantLock
Java 提供了兩種鎖機制來控制多個執行緒對共享資源的互斥訪問,第一個是 JVM 實現的 synchronized,而另一個是 JDK 實現的 ReentrantLock。 synchronized synchronized關鍵字最主要幾種使用方式: (1)同步一個程式碼塊: 只作用
Java併發學習筆記(九)-原子類AtomicInteger
AtomicInteger能夠保證對一個整型的操作是原子性。像i++這個操作不是原子操作,存在競態條件,所以需要加鎖,但是加鎖的效能不高,如果僅僅為了對一個整數加1。我們來看下他的實現。 private volatile int value; AtomicInte
JAVA中的BigInteger與BigDecimal類功能強大
取余 並且 log 加減乘除 value java 構造函數 () eof BigInteger類是java為了處理大數字二專門制作的類,可以處理很大的數字(理論上無限大),並且可以實現大數字的類似於int所有數學運算。對算法題來說,再也不怕出現超出int範圍的運算了! 同
JAVA中接口與抽象類
rac 構造 轉換 希望 就是 pub 成員變量 類型 規則 抽象類總結 抽象類的概念:是使用關鍵字abstract修飾的類就是抽象類; 抽象類的產生:當多個不能相互繼承的類具有相同的功能時,就需要將共同的信息向上抽取,放到公共的父類中;如果公共的父類只能描述所有子類都
Java併發控制:ReentrantLock Condition的使用
生產者-消費者(producer-consumer)問題,也稱作有界緩衝區(bounded-buffer)問題,兩個程序共享一個公共的固定大小的緩衝區。 其中一個是生產者,用於將訊息放入緩衝區;另外一個是消費者,用於從緩衝區中取出訊息。 問題出現在當緩衝區已經滿了,而此時生產者還想
【Java併發】synchronized之偏向鎖和輕量級鎖
synchronized之偏向鎖和輕量級鎖 上下文切換 synchronized 鎖的升級與對比 偏向鎖 輕量級鎖 參考 上下文切換 即使是單核處理器也支援多執行緒執行程式碼執行程式碼,CPU通
最新Java併發程式設計原理與實戰分享
課程大綱第1節你真的瞭解併發嗎? 00:27:48分鐘 | 第2節理解多執行緒與併發的之間的聯絡與區別 00:11:59分鐘 | 第3節解析多執行緒與多程序的聯絡以及上下文切換所
Java併發:Callable與Future
Callable Runnable 封裝一個非同步執行的任務,可以把它想象成為一個沒有引數和返回值的非同步方法。 Runnable runnable = new Runnable() { @Override public void run() { } }; r
Java併發(一)——Thread類介紹 .md
1 序言 最近面試期間,發現自己的併發知識比較薄弱,準備寫一個關於併發的系列學習筆記。 2 Thread類主要方法 相信Thread類大家並不陌生,在建立執行緒的時候幾乎都會用到它。下面咱們聊一聊Thread類中的主要方法。 2.1 start方法 開啟一個執行
深入理解Java併發之synchronized實現原理
關聯文章: 本篇主要是對Java併發中synchronized關鍵字進行較為深入的探索,這些知識點結合博主對synchronized的個人理解以及相關的書籍的講解(在結尾參考資料),如有誤處,歡迎留言。 執行緒安全是併發程式
Java學習筆記——介面與抽象類的區別
在某種意義上,介面是比抽象類更抽象的類,介面的作用更多是起到標準化、規範化的作用。 它們之間的區別: 1.抽象類可以有非抽象方法,而介面中只能有抽象方法(但在JDK1.8之後的版本中,介面可以擁有方法體,也就是說,介面也可以擁有非抽象方法了) 2.
Java併發程式設計入門與高併發面試
第6章 J.U.C之AQS講解 AQS是J.U.C的重要元件,也是面試的重要考點。這一章裡將重點講解AQS模型設計及相關同步元件的原理和使用,都非常實用,具體包括:CountDownLatch、Semaphore、CyclicBarrier、ReentrantLock與鎖、Condition等。這些元
Java併發程式設計原理與實戰
推薦視訊連結 java併發程式設計是一個優秀的開發者成長過程中繞不過去的挑戰。資料庫服務,Web服務,大資料處理框架,分散式服務等等,併發程式設計往往扮演著極其重要的角色。天下武功,唯快不破。要想提高效能,併發必不可少。 市面上大多數講解併發的視訊教程大多基於
(七)java併發程式設計synchronized+volatile(安全初始化模式例項)
安全釋出物件的安全性都來自於JMM提供的保證,而造成不正確的釋出原因,就是在”釋出一個共享物件”與”另一個執行緒訪問該物件”之間缺少一種Happen-Before排序. 不安全的釋出 package safe_unsafe_public
(六)java併發程式設計--synchronized同步塊
雖然前面文章的一些例項中已經使用synchronized關鍵字來實現執行緒的同步,但還是需要好好的理解一下。 一段程式碼或者一個方法被synchronized關鍵字標記我們就說這斷程式碼是同步塊。同步塊可以用來避免競爭條件。 synchronize
Java併發程式設計原理與實戰一(執行緒狀態及建立執行緒的多種方式)
一、為什麼要學習併發程式設計 1.發揮多處理的強大能力 2.建模的簡單性 3.非同步事件的簡化處理 4.響應更加靈敏的使用者介面 二、併發的缺點 1.安全性問題 多執行緒環境下 多個執行緒共享一個資源 對資源進行非原子性操作 2.活躍
Java-併發-鎖-synchronized
Java-併發-鎖-synchronized 摘要 本文會詳細說下synchronized的底層實現原理。 0x01 基本概念 每次只能有一個執行緒進入臨界區 保證臨界區內共享變數的可見性和有序性 成功進入synchronized區域的執行緒可以拿到物
JAVA學習之StringBuffer 與Sring類的區別(例項展示)
一、字串連線方法不同 String 類中用“+”連線,StringBuffer類中用append()方法連線; 例如如下程式碼: package Test; public class String
Java併發程式設計之原子操作類
原子操作類簡介 當更新一個變數的時候,多出現資料爭用的時候可能出現所意想不到的情況。這時的一般策略是使用synchronized解決,因為synchronized能夠保證多個執行緒不會同時更新該變數。然而,從jdk 5之後,提供了粒度更細、量級更輕,並且在多核處理器具有高效