015 可見性問題與volatile

2022-09-14 05:48:08 字數 1000 閱讀 1678

一 . 概述

可見性問題:

什麼是可見性問題?可見性問題的原因是什麼?

快取之中存在共享變數的副本,在有些時候,因為來不及維護副本和實體的一致性可能造成問題,這種問題就是可見性問題.

注意: 當我們解決的原子性的同時也就完成了可見性的問題的解決.

二 . 可見性性問題的例子:

public

class

visiableproblem extends thread

public

void

setrunning(boolean isrunning)

public

void

run()

system.

out.println("

isupdated的值被修改為為false,執行緒將被停止了");

}public

static

void

main(string args) throws interruptedexception

}

我們希望主線程可以同步標記位停止子執行緒,但是很讓人失望,子執行緒無法終止.

原因就是子執行緒使用了副本的內容,這個副本永遠是true的.

三 . 使用volatile解決可見性

我們只要在

private

volatile boolean isrunning = true;

增加乙個volatile就能解決這個問題.

[1]保證副本和主存之間的一致性

[2]打破指令重排序(這個在後面會說一下)

當我們看到了volatile的作用之後就知道怎麼為什麼能解決上述的問題了.

四 .分析

volatile可以解決可見性問題,但是無法解決原子性.

而執行緒的安全性問題的解決需要的是原子性而不是可見性,也就是說可見性是原子性的乙個保證,但無法保證原子性.

這也就決定了我們不能依靠volatile來實現同步.

變數可見性問題

併發程式設計時各個執行緒中無法獲取到共享變數的最新值。共享變數儲存在主記憶體中,通常情況下各個執行緒在使用某個共享變數時先將共享變數複製進執行緒工作記憶體中,後續使用到該變數時直接從當前執行緒工作記憶體中獲取變數值,此時如果其他執行緒更改了該共享變數值那麼當前執行緒無法實時更新到該變數的最新值。同步...

驗證Volatile可見性問題的關鍵

關鍵在於 while flag 中不能有從主記憶體讀取的操作 常見的兩種 thread.sleep,觸發了執行緒的重新排程,儲存當前執行緒上下文,即刷到主記憶體。存在synchronized,當獲取鎖以後,清空本地記憶體中共享變數,從主記憶體進行載入,在釋放鎖時將本地記憶體中共享變數重新整理到主記憶...

分布式與高併發 可見性問題 volatile(一)

1.1 引出可見性問題 public class volatiledemo system.out.println 迴圈結束 i start thread.sleep 1000 stop false 1.2 執行結果 1.3 執行結果分析 可見迴圈一直未結束,沒有輸出 system.out.print...