可見性、原子性和有序性

来源:https://www.cnblogs.com/tianzg/archive/2020/05/22/12940366.html

1 緩存導致的可見性問題 一個線程對共用變數的修改,另一個線程可以立即看到,這稱之為可見性。 Java記憶體模型規定所有的變數存儲在主記憶體中。每個線程都有自己的工作記憶體,線程在工作記憶體中保存了使用到的主記憶體中變數的副本拷貝,線程對變數的操作必須在工作記憶體中進行,不能直接讀寫主記憶體中的變數。不同線程之間 ...


1  緩存導致的可見性問題

  一個線程對共用變數的修改,另一個線程可以立即看到,這稱之為可見性。

  Java記憶體模型規定所有的變數存儲在主記憶體中。每個線程都有自己的工作記憶體,線程在工作記憶體中保存了使用到的主記憶體中變數的副本拷貝,線程對變數的操作必須在工作記憶體中進行,不能直接讀寫主記憶體中的變數。不同線程之間無法訪問對方工作記憶體的變數。線程之間共用變數值的傳遞均需要通過主記憶體來完成。

  當線程1對共用變數A進行修改之後,線程2的工作記憶體中A可能還不是最新的值。這時候線程1的操作對線程2就不具有可見性。

 

2  線程切換帶來的原子性問題

  我們把一個或者多個操作在CPU執行期間不被打斷的特性成為原子性。

  Java中的一條語句,在翻譯為機器碼之後,可能對應的是多個指令。

  比如:i++這個操作至少需要3條指令;

  1. 把 i 的值從記憶體=載入到寄存器;
  2. 執行+1操作;
  3. 把值寫入記憶體;

  假如 i=0,兩個線程同時執行該操作,可能線程1執行完第一步,就切換到線程2執行,本來兩個線程各執行一次後 i 的值應該為 2 ,此時就出現 兩次遞增操作後值為 1 的現象;

 

3  編譯優化帶來的有序性問題

  Java程式中,如果在本線程中觀察,所有的操作都是有序的;如果在另一個線程觀察,所有的操作都是無序的。前半句指的是線程內表現為串列的語義,後半句指的是指令重排序和主記憶體和工作記憶體同步延遲的問題。

  為了充分利用處理器的性能,處理器會對輸入的代碼進行亂序執行。在計算之後將亂序執行的結果重組,並保證該結果和順序執行的結果一致,但是並不保證程式中各個語句的計算順序和輸入代碼的順序一致。Java虛擬機也有類似的指令重排序優化。

  比如:Object  obj = new Object(),

  這條語句對應的指令為:

  1. 分配一塊記憶體M;
  2. 在M上初始化 Object 對象;
  3. 將M的地址賦值給 obj;

  電腦經過優化後可能先執行第三步,再第二步,如果執行完第三步後切換到別的線程,若此時訪問該變數則會發生空指針異常;


您的分享是我們最大的動力!

更多相關文章
  • 一、JML初探 ​ 作為一種形式化語言,可以約束 代碼中類和方法的狀態和行為形成規格,通過將一系列具體代碼實現抽象成明確的行為介面,可以形成一種契約式編程模式, 設計者無需考慮實際的數據結構與演算法,可以聚焦於程式的整體邏輯, 形式化語言的無二義性能讓實現者準確理解介面功能,根據問題需要選擇合適的實現 ...
  • 首先安裝Erlang環境 因為 RabbitMQ 需要 erlang 環境的⽀持,所以必須先安裝 erlang 。 如果只是使用RabbitMQ,個人推薦使用RabbitMQ公司維護的 "erlang" 版本,該版本只保留了與RabbltMQ相關的功能, centOS6與7版本的都有,還有erlan ...
  • 【導讀】:前面的文章介紹了移動平均濾波器、IIR濾波器、梳狀濾波器,今天來談談FIR濾波器的設計實現。 本篇文章依然採用4W1H進行描述,從 What Why Where When How 幾個維度展開。為了便於理解4W1H,依然把5W1H的圖附上。 FIR濾波器之What? LTI線性時不變系統沖 ...
  • [導讀]:前面一篇文章關於IIR/移動平均濾波器設計的文章。本文來聊一聊陷波濾波器,該濾波器在混入諧波干擾時非常有用,演算法簡單,實現代價低。本文來一探其在機理、應用場景。 註:儘量在每篇文章寫寫摘要,方便閱讀。信息時代,大家時間都很寶貴,如此亦可節約粉絲們的寶貴時間。 前文所說學習的倡導2W1H原則 ...
  • 本文是學習筆記中的思維導圖,感覺思維導圖是個好東西,可以加深記憶、構建知識體系、還能為將來的複習提供便利。 完整筆記的地址在文末。說明下,併發編程的底層原理和JMM我打算背下來。 完整筆記地址: "java併發編程藝術學習筆記gitbook" "java併發編程藝術學習筆記github" 下麵這個是 ...
  • 一、反射的概念 1.反射的概念是有Smith在1982年首次提出,主要是指程式可以訪問、檢測和修改它本身狀態或者行為的一種能力,並且根據自身行為的狀態和結果,調整或者修改應用所描述行為的狀態和相關的語義。 2.Java中,反射是一種強大的工具,它使您能夠創建靈活的代碼,這些代碼可以在運行時進行裝配, ...
  • 設計子程式 子程式一:在指定的位置,用指定的顏色,顯示一個用0結束的字元串 舉例:在屏幕的8行3列,用綠色顯示data段中的字元串 assume cs:code data segment db 'Welcome to masm!',0 data ends code segment start: mo ...
  • [TOC] QuantLib 金融計算——案例之普通利率互換分析(2) 概述 QuantLib 中涉及利率互換的功能大致分為兩大類: 對存續的利率互換合約估值; 根據利率互換合約的成交報價推算隱含的期限結構。 這兩類功能是緊密聯繫的,根據最新報價推算出的期限結構通常可以用來對存續合約進行估值。 本文 ...
一周排行
  • 一:背景 1. 講故事 曾今在項目中發現有同事自定義結構體的時候,居然沒有重寫Equals方法,比如下麵這段代碼: static void Main(string[] args) { var list = Enumerable.Range(0, 1000).Select(m => new Point ...
  • 最近一個朋友有個關於素數的小東西要寫一下,素數是什麼呢?除了1和他本身不能被其他數整除,那麼這個數就是素數,1除外哦。我們知道概念那就很簡單了,直接代碼擼起。 ...
  • 前言 在開發編程中,我們經常會遇到功能非常相似的功能模塊,只是他們的處理的數據不一樣,所以我們會分別採用多個方法來處理不同的數據類型。但是這個時候,我們就會想一個問題,有沒有辦法實現利用同一個方法來傳遞不同種類型的參數呢? 這個時候,泛型也就因運而生,專門來解決這個問題的。 泛型是在C 2.0就推出 ...
  • 本文章主要用於介紹在Asp.Net Mvc(C#)中使用Fleck製作一個Html5的即時聊天室,含有完整代碼和演示Demo。 ...
  • 出庫單的功能。能學習了出庫單管理之後,WMS的 主體功能算是完成了。當然一個成熟的WMS還包括了盤點,報表,策略規則,移庫功能及與其他系統(ERP、TMS等)的介面,實現無縫集成,打破信息孤島,讓數據實時、準確和同步。 ...
  • Data StructureThere're two types of variables in C#, reference type and value type.Enum:enum Color{Red=0,Green=1}//equals to enum Color{Red,//start fr... ...
  • 0. 前言 該項目使用Maven進行管理和構建,所以需要預先配置好Maven。嗯,在這個系列里就不做過多的介紹了。 1. 創建項目 先創建一個pom.xml 文件,添加以下內容: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http: ...
  • API 概述 API(Application Programming Interface),應用程式編程介面。 Java API是一本程式員的 字典 ,是JDK中提供給我們使用的類的說明文檔。 這些類將底層的代碼實現封裝了起來,我們不需要關心這些類是如何實現的,只需要學習這些類如何使用即可。 所以我 ...
  • 女程式員是這麼徵婚的: SELECT * FROM 男人們 WHERE 未婚=true and 同性戀=false and 有房=true and 有車=true and 條件 in (帥氣,紳士,大度,氣質,智慧,溫柔,體貼,會浪漫,活潑,可愛,最好還能帶孩子) and 年齡 between(24 ...
  • 有很多剛學習軟體測試的小伙伴,都會在網路上找尋各種學習資料,去提升自己的專業技能水平。因此,我決定定期分享我整理收集的一些軟體測試的測試工具下載、面試寶典、視頻教學合集。都整理好了,有需要的可以關註我(獲取方式在文末) 軟體測試的學習,不止是基礎理論,還需要學習測試工具的用法,如介面工具Postma ...