日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

線程安全性是我們在進行 JAVA 并發(fā)編程的時候必須要先考慮清楚的一個問題。這個類在單線程環(huán)境下是沒有問題的,那么我們就能確保它在多線程并發(fā)的情況下表現(xiàn)出正確的行為嗎?

我這個人,在沒有副業(yè)之前,一心撲在工作上面,所以處理的蠻得心應(yīng)手,心態(tài)也一直保持的不錯;但有了副業(yè)之后,心態(tài)就變得像坐過山車一樣。副業(yè)收入超過主業(yè)的時候,人特別亢奮,像打了雞血一樣;副業(yè)遲遲打不開局面的時候,人就變得惶惶不可終日。

仿佛我就只能是個單線程,副業(yè)和主業(yè)并行開啟多線程模式的時候,我就變得特別沒有安全感,盡管整體的收入比沒有副業(yè)之前有了很大的改善。

怎么讓我自己變得有安全感,我還沒想清楚(你要是有好的方法,請一定要告訴我)。但怎么讓一個類在多線程的環(huán)境下是安全的,有 3 條法則,讓我來告訴你:

  1. 不在線程之間共享狀態(tài)變量
  2. 將狀態(tài)變量改為不可變
  3. 訪問狀態(tài)變量時使用同步
Java 并發(fā)編程:如何保證共享變量的原子性?

 

01 那么,狀態(tài)變量是什么?

我們先來看一個沒有狀態(tài)變量的類吧,代碼示例如下。

class Chenmo {
 public void write() {
 System.out.println("我尋了半生的春天,你一笑便是了。");
 }
}

Chenmo 這個類就是無狀態(tài)變量的,它只有一個方法,既沒有成員變量,也沒有類變量。任何訪問它的線程都不會影響另外一個線程的結(jié)果,因為兩個線程之間沒有共享任何的狀態(tài)變量。所以可以下這樣一個結(jié)論:無狀態(tài)變量的類一定是線程安全的。

然后我們再來看一個有狀態(tài)變量的類。假設(shè)沉默(Chenmo 類)每寫一行字(write() 方法),就要做一次統(tǒng)計,這樣好找出版社索要稿費。我們?yōu)?Chenmo 類增加一個統(tǒng)計的字段,代碼示例如下。

class Chenmo {
 private long count = 0;
 public void write() {
 System.out.println("我尋了半生的春天,你一笑便是了。");
 count++;
 }
}

Chenmo 類在單線程環(huán)境下是可以準(zhǔn)確統(tǒng)計出行數(shù)的,但多線程的環(huán)境下就不行了。因為遞增運算 count++ 可以拆分為三個操作:讀取 count,將 count 加 1,將計算結(jié)果賦值給 count。多線程的時候,這三個操作發(fā)生的時序可能是混亂的,最終統(tǒng)計出來的 count 值就會比預(yù)期的值小。

假定線程 A 正在修改 count 變量,這時候就要防止線程 B 或者線程 C 使用這個變量,從而保證線程 B 或者線程 C 在使用 count 的時候是線程 A 修改過后的狀態(tài)。

02 怎么防止呢?

可以在 write() 方法上加一個 synchronized 關(guān)鍵字。代碼示例如下。

class Chenmo {
 private long count = 0;
 public synchronized void write() {
 System.out.println("我尋了半生的春天,你一笑便是了。");
 count++;
 }
}

關(guān)鍵字 synchronized 是一種最簡單的同步機制,可以確保同一時刻只有一個線程可以執(zhí)行 write(),也就保證了 count++ 在多線程環(huán)境下是安全的。

在編寫并發(fā)應(yīng)用程序時,我們必須要保持一種正確的觀念,那就是——首先要確保代碼能夠正確運行,然后再是如何提高代碼的性能。

但眾所周知,synchronized 的代價是昂貴的,多個線程之間訪問 write() 方法是互斥的,線程 B 訪問的時候必須要等待線程 A 訪問結(jié)束,這無法體現(xiàn)出多線程的核心價值。

java.util.concurrent.atomic.AtomicInteger 是一個提供原子操作的 Integer 類,它提供的加減操作是線程安全的。于是我們可以這樣修改 Chenmo 類,代碼示例如下。

class Chenmo {
 private AtomicInteger count = new AtomicInteger(0);
 public void write() {
 System.out.println("我尋了半生的春天,你一笑便是了。");
 count.incrementAndGet();
 }
}

write() 方法不再需要 synchronized 關(guān)鍵字保持同步,于是多線程之間就不再需要以互斥的方式來調(diào)用該方法,可以在一定程度上提升統(tǒng)計的效率。

某一天,出版社統(tǒng)計稿費的形式變了,不僅要統(tǒng)計行數(shù),還要統(tǒng)計字?jǐn)?shù),于是 Chenmo 類就需要再增加一個成員變量了。代碼示例如下。

class Chenmo {
 private AtomicInteger lineCount = new AtomicInteger(0);
 private AtomicInteger wordCount = new AtomicInteger(0);
 public void write() {
 String words = "我這一輩子,走過許多地方的路,行過許多地方的橋,看過許多次的云,喝過許多種類的酒,卻只愛過一個正當(dāng)年齡的人。";
 System.out.println(words);
 lineCount.incrementAndGet();
 wordCount.addAndGet(words.length());
 }
}

03 你覺得這段代碼是線程安全的嗎?

結(jié)果顯而易見,這段代碼不是線程安全的。因為 lineCount 和 wordCount 是兩個變量,盡管它們各自是線程安全的,但線程 A 進行 lineCount 加 1 的時候,并不能夠保證線程 B 是在線程 A 執(zhí)行完 wordCount 統(tǒng)計后開始 lineCount 加 1 的。

Java 并發(fā)編程:如何保證共享變量的原子性?

 

04 該怎么辦呢?

方法也很簡單,代碼示例如下。

class Chenmo {

private int lineCount = 0;

private int wordCount = 0;

public void write() {

String words = "我這一輩子,走過許多地方的路,行過許多地方的橋,看過許多次的云,喝過許多種類的酒,卻只愛過一個正當(dāng)年齡的人。";

System.out.println(words);

synchronized (this) {

lineCount++;

wordCount++;

}

}

}

對行數(shù)統(tǒng)計(lineCount++)和字?jǐn)?shù)統(tǒng)計(wordCount++)的代碼進行加鎖,保證這兩行代碼是原子性的。也就是說,線程 B 在進行統(tǒng)計的時候,必須要等待線程 A 統(tǒng)計完之后再開始。

原文鏈接:https://juejin.im/post/5d7ee216e51d4561af16ddb2

synchronized (lock) {...} 是 Java 提供的一種簡單的內(nèi)置鎖機制,用于保證代碼塊的原子性。線程在進入加鎖的代碼塊之前自動獲取鎖,并且退出代碼塊的時候釋放鎖,可以保證一組語句作為一個不可分割的單元被執(zhí)行。

分享到:
標(biāo)簽:并發(fā) 編程 Java
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定