為什么要出現并發?并發的三要素

大家好,我是"java繼父"伯約,假如這篇對大家有幫助的話求一個贊,另外文章末尾放了我從小白到架構師多年的學習資料。

1.為什么需要多線程

眾所周知,CPU、內存、I/O 設備的速度是有極大差異的,為了合理利用 CPU 的高性能,平衡這三者的速度差異,計算機體系結構、操作系統、編譯程序都做出了貢獻,主要體現為:

  • CPU 增加了緩存,以均衡與內存的速度差異;// 導致 可見性問題
  • 操作系統增加了進程、線程,以分時復用 CPU,進而均衡 CPU 與 I/O 設備的速度差異;// 導致 原子性問題
  • 編譯程序優化指令執行次序,使得緩存能夠得到更加合理地利用。// 導致 有序性問題

2.線程不安全示例

如果多個線程對同一個共享數據進行訪問而不采取同步操作的話,那么操作的結果是不一致的。

以下代碼演示了 1000 個線程同時對 cnt 執行自增操作,操作結束之后它的值有可能小于 1000。

public class ThreadUnsafeExample {private int cnt = 0;public void add() {cnt++;}public int get() {return cnt;}
}
public static void main(String[] args) throws InterruptedException {final int threadSize = 1000;ThreadUnsafeExample example = new ThreadUnsafeExample();final CountDownLatch countDownLatch = new CountDownLatch(threadSize);ExecutorService executorService = Executors.newCachedThreadPool();for (int i = 0; i < threadSize; i++) {executorService.execute(() -> {example.add();countDownLatch.countDown();});}countDownLatch.await();executorService.shutdown();System.out.println(example.get());
}
997 // 結果總是小于1000

3.并發出現問題的根源: 并發三要素

上述代碼輸出為什么不是1000? 并發出現問題的根源是什么?

可見性: CPU緩存引起

可見性:一個線程對共享變量的修改,另外一個線程能夠立刻看到。

舉個簡單的例子,看下面這段代碼:

//線程1執行的代碼
int i = 0;
i = 10;//線程2執行的代碼
j = i;

假若執行線程1的是CPU1,執行線程2的是CPU2。由上面的分析可知,當線程1執行 i =10這句時,會先把i的初始值加載到CPU1的高速緩存中,然后賦值為10,那么在CPU1的高速緩存當中i的值變為10了,卻沒有立即寫入到主存當中。

此時線程2執行 j = i,它會先去主存讀取i的值并加載到CPU2的緩存當中,注意此時內存當中i的值還是0,那么就會使得j的值為0,而不是10.

這就是可見性問題,線程1對變量i修改了之后,線程2沒有立即看到線程1修改的值。

原子性: 分時復用引起

原子性:即一個操作或者多個操作 要么全部執行并且執行的過程不會被任何因素打斷,要么就都不執行。

舉個簡單的例子,看下面這段代碼:

int i = 1;// 線程1執行
i += 1;// 線程2執行
i += 1;

這里需要注意的是:i += 1需要三條 CPU 指令

  1. 將變量 i 從內存讀取到 CPU寄存器;
  2. 在CPU寄存器中執行 i + 1 操作;
  3. 將最后的結果i寫入內存(緩存機制導致可能寫入的是 CPU 緩存而不是內存)。

由于CPU分時復用(線程切換)的存在,線程1執行了第一條指令后,就切換到線程2執行,假如線程2執行了這三條指令后,再切換會線程1執行后續兩條指令,將造成最后寫到內存中的i值是2而不是3。

有序性: 重排序引起

有序性:即程序執行的順序按照代碼的先后順序執行。舉個簡單的例子,看下面這段代碼:

int i = 0;              
boolean flag = false;
i = 1;                //語句1  
flag = true;          //語句2

上面代碼定義了一個int型變量,定義了一個boolean類型變量,然后分別對兩個變量進行賦值操作。從代碼順序上看,語句1是在語句2前面的,那么JVM在真正執行這段代碼的時候會保證語句1一定會在語句2前面執行嗎? 不一定,為什么呢? 這里可能會發生指令重排序(Instruction Reorder)。

在執行程序時為了提高性能,編譯器和處理器常常會對指令做重排序。重排序分三種類型:

  • 編譯器優化的重排序。編譯器在不改變單線程程序語義的前提下,可以重新安排語句的執行順序。
  • 指令級并行的重排序。現代處理器采用了指令級并行技術(Instruction-Level Parallelism, ILP)來將多條指令重疊執行。如果不存在數據依賴性,處理器可以改變語句對應機器指令的執行順序。
  • 內存系統的重排序。由于處理器使用緩存和讀 / 寫緩沖區,這使得加載和存儲操作看上去可能是在亂序執行。

從 java 源代碼到最終實際執行的指令序列,會分別經歷下面三種重排序:

????????上述的 1 屬于編譯器重排序,2 和 3 屬于處理器重排序。這些重排序都可能會導致多線程程序出現內存可見性問題。對于編譯器,JMM 的編譯器重排序規則會禁止特定類型的編譯器重排序(不是所有的編譯器重排序都要禁止)。對于處理器重排序,JMM 的處理器重排序規則會要求 java 編譯器在生成指令序列時,插入特定類型的內存屏障(memory barriers,intel 稱之為 memory fence)指令,通過內存屏障指令來禁止特定類型的處理器重排序(不是所有的處理器重排序都要禁止)。

4.粉絲福利

最新很多同學問我有沒有java學習資料,我根據我從小白到架構師多年的學習經驗整理出來了一份50W字面試解析文檔、簡歷模板、學習路線圖、java必看學習書籍、需要的小伙伴可以關注我的
公眾號:“Tom聊架構”,回復暗號:“578”即可獲取

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:
http://www.pswp.cn/news/536773.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/536773.shtml
英文地址,請注明出處:http://en.pswp.cn/news/536773.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Vue編寫登錄注冊頁面前端校驗

登錄注冊校驗 template頁面 <div class"app-login"><!--登錄 --><div class"form"><el-form ref"form" size"large" autocomplete"off" v-if"isLogin" :model"registerData" :r…

FXCM福匯官網:深入解析BOLL指標的喇叭口形態及含義

BOLL指標是一種通過布林線&#xff08;Bollinger Bands&#xff09;的上軌線、中軌線和下軌線的相互關系來判斷市場趨勢和波動性的技術分析工具。BOLL指標的喇叭口形態包括開口型、收口型和緊口型&#xff0c;它們各自具有獨特的含義。 《FXCM福匯官網開戶》 1. 開口型喇叭口…

cesium實現二三維聯動

記錄項目中實現二三維地圖聯動 效果如下&#xff1a; 第一步&#xff1a;現在頁面中加載二三維地圖&#xff08;地圖的初始化已省略&#xff09; <template><div><div><button click"show">二三維聯動</button></div><div&…

Go Web 編程

Go Web 編程 更新于 1年前 一步步帶你進入 Go Web 編程的世界,讓我們開始探索吧! 文檔類型:系統文檔 文章統計:96 篇,字數 12.52 萬,點贊 508 文章列表所有討論 基本信息 關于本書 第一章. Go 環境配置 01.0. Go 環境配置 01.1. 安裝 Go 01.2. GOPATH 與工作空間 …

經典文獻閱讀之--RenderOcc(使用2D標簽訓練多視圖3D Occupancy模型)

0. 簡介 3D占據預測在機器人感知和自動駕駛領域具有重要的潛力&#xff0c;它將3D場景量化為帶有語義標簽的網格單元。最近的研究主要利用3D體素空間中的完整占據標簽進行監督。然而&#xff0c;昂貴的注釋過程和有時模糊的標簽嚴重限制了3D占據模型的可用性和可擴展性。為了解…

[HADOOP]數據傾斜的避免和處理

避免數據傾斜 初始設計方面&#xff1a; 設計階段考慮數據分布&#xff0c;并盡可能確保數據均勻分布。 預處理數據&#xff1a; 在數據加載到 Hadoop 之前進行預處理&#xff0c;以減少傾斜。使用抽樣或統計方法來了解數據分布特征&#xff0c;并據此調整。 使用合適的Partiti…

EtherCAT主站SOEM -- 11 -- EtherCAT從站 XML 文件解析

EtherCAT主站SOEM -- 11 -- EtherCAT從站 XML 文件解析 1 EtherCAT 從站信息規范1.1 XML 文件說明1.1.1 XML 數據類型1.1.2 EtherCATInfo1.1.3 Groups1.1.4 Devices1.1.5 Modules1.1.6 Types1.1.6.1 AccessType 的組成1.1.6.2 ArraylnfoType 的組成1.1.6.3 DeviceType 的組成1.…

Mendelson AS2 介紹下載和配置

最近與一家國外公司做EDI對接&#xff0c;并且EDI通訊工具是基于AS2協議的。目前開源的as2的開源項目有openas2,Mendelson AS2&#xff0c;和國人寫的freeas2但是&#xff0c;現在freeas2已經被從開源中國不能下載了&#xff0c;變為收費的版本了。 如果你需要使用基于AS2協議…

動態規劃、DFS 和回溯算法:二叉樹問題的三種視角

動態規劃、DFS 和回溯算法&#xff1a;二叉樹問題的三種視角 在計算機科學中&#xff0c;算法是解決問題的核心。特別是對于復雜的問題&#xff0c;不同的算法可以提供不同的解決方案。在本篇博客中&#xff0c;我們將探討三種算法&#xff1a;動態規劃、深度優先搜索&#xf…

掌握常用Docker命令,輕松管理容器化應用

Docker是一個開源的應用容器引擎&#xff0c;它可以讓開發者將應用程序及其依賴打包到一個輕量級、可移植的容器中&#xff0c;然后發布到任何流行的Linux機器或Windows機器上&#xff0c;也可以實現虛擬化。容器是完全使用沙箱機制&#xff0c;相互之間不會有任何接口。下面介…

Python基礎(九、重要的全局變量)

文章目錄 全局變量是什么&#xff1f;引用全局變量修改全局變量注意事項結語 全局變量是什么&#xff1f; 首先&#xff0c;全局變量是在函數外部定義的變量&#xff0c;它可以在程序的任何地方被訪問。就好像一家人共用的盤子&#xff0c;隨手可以拿來用&#xff0c;但也可能…

智能倉儲管理系統設計與實現

智能倉儲管理系統設計與實現 第一章 緒論 1.1 設計背景 物聯網&#xff08;英文&#xff1a;Internet of Things&#xff0c;縮寫&#xff1a;IoT&#xff09;是萬物相連的互聯網&#xff0c;即把所有物品通過信息傳感設備與互聯網連接起來&#xff0c;以實現智能化識別、定位、…

【Unity入門】NGUI和UGUI比較

目錄 NGUI組件比較多&#xff0c;比較常用的有UGUI組件比較少&#xff0c;比較常用的有NGUI和UGUI比較 現在主流項目中基本上都是NGUI和UGUI&#xff0c;那么到底選哪個&#xff0c;我們先來做個比較 圖集處理功能比較 NGUI需要使用工具手動拼接圖片成圖集。 UGUI開發期間可以直…

Java網絡爬蟲拼接姓氏,名字并寫出到txt文件(實現隨機取名)

目錄 1.爬取百家姓1.爬取代碼2.爬取效果 2.爬取名字1.篩選男生名字2.篩選女生名字 3.數據處理&#xff08;去除重復&#xff09;4.拼接數據5.將數據寫出到文件中 1.爬取百家姓 目標網站&#xff0c;僅作為實驗目的。 ①爬取姓氏網站&#xff1a; https://hanyu.baidu.com/shic…

小狐貍ChatGPT系統 H5前端底部菜單導航文字修改方法

小狐貍ChatGPT系統后端都前端都是編譯過的&#xff0c;需要改動點什么非常難處理&#xff0c;開源版修改后也需要編譯后才能使用&#xff0c;大部分會員也不會使用&#xff0c;像簡單的修改下底部菜單文字、圖標什么的可以對照處理。這里以小狐貍ChatGPT系統1.9.2版本H5端為例&…

JWT signature does not match locally computed signature

1. 問題背景 最近在協助團隊小盆友調試一個驗簽問題&#xff0c;結果還“節外生枝”了&#xff0c;原來不是簽名過程的問題&#xff0c;是token的問題。 當你看到“JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not…

多維時序 | MATLAB實CNN-Mutilhead-Attention卷積神經網絡融合多頭注意力機制多變量時間序列預測

多維時序 | MATLAB實CNN-Mutilhead-Attention卷積神經網絡融合多頭注意力機制多變量時間序列預測 目錄 多維時序 | MATLAB實CNN-Mutilhead-Attention卷積神經網絡融合多頭注意力機制多變量時間序列預測預測效果基本介紹模型描述程序設計參考資料 預測效果 基本介紹 多維時序 | …

異或運算^簡述

異或運算&#xff1a;^ 兩個變量之間異或運算時&#xff0c;其二進制位相同取0&#xff0c;不同取1. 示例&#xff1a;a10 (0b 0000 1010) b3 (0b 0000 0011) a^b9(0b 0000 1001) 據此可以推算異或運算"^"有以下特性&#xff1a; a^a0 (0b 0000 0000)…

python使用apscheduler定時任務,固定周幾運行程序

在add_job中添加參數day_of_week即可&#xff1a; day_of_week "0"表示&#xff1a;只有周一運行day_of_week "0-4"表示&#xff1a;周一到周五運行day_of_week "0,1,2"表示&#xff1a;周一二三運行 示例程序 from datetime import datet…

IDEA基本設置

本博客適用于純新手小白&#xff0c;或者剛下載IDEA想要優化開發添加配置的讀者。 基礎設置 滾輪調整字體大小 打開 IntelliJ IDEA。 轉到菜單欄中的 “File” -> “Settings”&#xff08;Windows/Linux&#xff09;或 “IntelliJ IDEA” -> “Preferences”&#xff…