溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java項目中實現(xiàn)多線程并發(fā)編程的條件有哪些

發(fā)布時間:2020-11-20 15:35:36 來源:億速云 閱讀:184 作者:Leah 欄目:編程語言

這期內(nèi)容當中小編將會給大家?guī)碛嘘PJava項目中實現(xiàn)多線程并發(fā)編程的條件有哪些,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

一、原子性

原子,一個不可再被分割的顆粒。原子性,指的是一個或多個不能再被分割的操作。

int i = 1; // 原子操作
i++; // 非原子操作,從主內(nèi)存讀取 i 到線程工作內(nèi)存,進行 +1,再把 i 寫到朱內(nèi)存。

雖然讀取和寫入都是原子操作,但合起來就不屬于原子操作,我們又叫這種為“復合操作”。

我們可以用synchronized 或 Lock 來把這個復合操作“變成”原子操作。

例子:

 private synchronized void increase(){
    i++;
  }

 private int i = 0;
  Lock mLock = new ReentrantLock();

  private void increase() {
    mLock.lock();
    try {
      i++;
    } finally{
      mLock.unlock();
    }
  }

這樣我們就可以把這個一個方法看做一個整體,一個不可分割的整體。

除此之前,我們還可以用java.util.concurrent.atomic里的原子變量類,可以確保所有對計數(shù)器狀態(tài)訪問的操作都是原子的。

例子:

AtomicInteger mAtomicInteger = new AtomicInteger(0);
 
  private void increase(){
    mAtomicInteger.incrementAndGet();
  }

二、可見性

當多線程訪問某一個(同一個)變量時,其中一條線程對此變量作出修改,其他線程可以立刻讀取到最新修改后的變量。

int i = 0;
// 線程 1 執(zhí)行
i++;

// 線程 2 執(zhí)行
System.out.print("i=" + i);

即使是在執(zhí)行完線程里的 i++ 后再執(zhí)行線程 2,線程 2 的輸入結果也會有 2 個種情況,一個是 0 和 1。

因為 i++ 在線程 1(CPU1)中做完了運算,并沒有立刻更新到主內(nèi)存當中,而線程 2(CPU2)就去主內(nèi)存當中讀取并打印,此時打印的就是 0。

synchronized和Lock能夠保證可見性。

另外volatile關鍵字也可以解決這個問題(下一篇會講到)。

三、有序性

我們都知道處理器為了擁有更好的運算效率,會自動優(yōu)化、排序執(zhí)行我們寫的代碼,但會確保執(zhí)行結果不變。

例子:

int a = 0; // 語句 1
int b = 0; // 語句 2
i++; // 語句 3
b++; // 語句 4

這一段代碼的執(zhí)行順序很有可能不是按上面的 1、2、3、4 來依次執(zhí)行,因為 1 和 2 沒有數(shù)據(jù)依賴,3 和 4 沒有數(shù)據(jù)依賴, 2、1、4、3 這樣來執(zhí)行可以嗎?完全沒問題,處理器會自動幫我們排序。

在單線程看來并沒有什么問題,但在多線程則很容易出現(xiàn)問題。

再來個例子:

// 線程 1
init();
inited = true;

// 線程 2
while(inited){
	work();
}

init(); 與 inited = true; 并沒有數(shù)據(jù)的依賴,在單線程看來,如果把兩句的代碼調(diào)換好像也不會出現(xiàn)問題。

但此時處于一個多線程的環(huán)境,而處理器真的把這兩句代碼重新排序,那問題就出現(xiàn)了,若線程 1 先執(zhí)行 inited = true; 此時,init() 并沒有執(zhí)行,線程 2 就已經(jīng)開始調(diào)用 work() 方法,此時很可能造成一些奔潰或其他 BUG 的出現(xiàn)。

synchronized和Lock能確保原子性,能讓多線程執(zhí)行代碼的時候依次按順序執(zhí)行,自然就具有有序性。

而volatile關鍵字也可以解決這個問題,volatile 關鍵字可以保證有序性,讓處理器不會把這行代碼進行優(yōu)化排序。

上述就是小編為大家分享的Java項目中實現(xiàn)多線程并發(fā)編程的條件有哪些了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI