java 多執行緒併發實質
首先我們都知道多執行緒在獲取共享資源時,往往會出現意想不到的結果,這是為什麼呢?執行緒獲取共享資源的過程如下圖:
首先我們需要了解jvm記憶體結構,在這裡不過多說明,由上圖我們可以知道,在jvm記憶體中分為獨立記憶體和共享記憶體,獨立記憶體是我們每個執行緒獨有的資訊,而共享記憶體就是我們每個執行緒都可以訪問的資料,由於執行緒在獲取共享資料的時候是一個過程,有左部分圖我們可以知道,首先我們獲取共享資料讀取到每個執行緒的快取空間,然後進行載入讀取賦值寫入同步等操作,在多執行緒併發訪問時我們如果一個執行緒獲取了堆記憶體中的資料,此時其他執行緒也訪問此共享資料,我們第一個執行緒資料還沒有修改更新到堆記憶體中,那麼第二個執行緒此時讀取資料就是髒資料。我們如果加上了Synchronizer等同於把我們執行過程作為一個整體,直接讀取堆記憶體資料不在讀取快取,這樣我們就可以實時獲取最新資料,那麼volatile怎麼回事呢?它是直接讀取堆記憶體資料,也就是我們常說的可見性,但是他並沒有處理我們執行緒獲取的原子性。
相關推薦
java 多執行緒併發實質
首先我們都知道多執行緒在獲取共享資源時,往往會出現意想不到的結果,這是為什麼呢?執行緒獲取共享資源的過程如下圖: 首先我們需要了解jvm記憶體結構,在這裡不過多說明,由上圖我們可以知道,在jvm記憶體中分為獨立記憶體和共享記憶體,獨立記憶體是我們每個執行緒獨有的資訊,而
Java多執行緒-併發之執行緒池
執行緒池有了解嗎? 答: java.util.concurrent.ThreadPoolExecutor 類就是一個執行緒池。客戶端呼叫ThreadPoolExecutor.submit(Runnable task) 提交任務,執行緒池內部維護的工作者執行緒的數量就是該執行緒池的執行
Java多執行緒-併發之synchronized 關鍵字
synchronized 關鍵字 答: 底層實現: 進入時,執行 monitorenter,將計數器 +1,釋放鎖 monitorexit 時,計數器 -1 當一個執行緒判斷到計數器為 0 時,則當前鎖空閒,可以佔用;反之,當前執行緒進入等待狀態 含義
Java多執行緒-併發之sleep() 和 wait(n) 、 wait() 的區別
sleep() 和 wait(n) 、 wait() 的區別 答: sleep 方法:是 Thread 類的靜態方法,當前執行緒將睡眠 n 毫秒,執行緒進入阻塞狀態。當睡眠時間到了,會接觸阻塞,進入可執行狀態,等待 CPU 的到來。睡眠不釋放鎖(如果有的話) wai
Java多執行緒-併發之多執行緒產生死鎖的4個必要條件?如何避免死鎖?
多執行緒產生死鎖的4個必要條件? 答: 互斥條件:一個資源每次只能被一個執行緒使用 請求與保持條件:一個執行緒因請求資源而阻塞時,對已獲得的資源保持不放 不剝奪條件:程序已經獲得的資源,在未使用完之前,不能強行剝奪 迴圈等待條件:若干執行緒之間形成一種頭
Java多執行緒-併發之執行緒和程序的區別
執行緒和程序的區別 答: 程序是一個“執行中的程式”,是系統進行資源分配和排程的一個獨立單位 執行緒是程序的一個實體,一個程序中擁有多個執行緒,執行緒之間共享地址空間和其他資源(所以通訊和同步等操作執行緒比程序更加容易) 執行緒上下文的切換比程序上下文切換要快
Java多執行緒-併發之如何制定多個執行緒的執行順序?
文章目錄 如何讓10個執行緒按照順序列印0123456789? 程式碼如下: 1.建立一個鎖物件類 2.建立一個執行緒類 3.測試類 如何讓10個執行緒按照順序列印012
【Java多執行緒併發總結】Thread類的常用方法(join、yield等)---執行緒的基礎操作篇
啟動(start) 最基本的操作,呼叫Runnable中的run方法,無返回值。 new Thread(new Test()).start(); 休眠(sleep) 使當前執行緒休眠一段時間,預設為毫秒級,最高可以精確到納秒,呼叫的方法為slee
JAVA多執行緒併發Demo
一個最簡單的多執行緒併發demo: 主函式: public class multithreadReq { private static final int THREADNUM = 5;/
一、Java多執行緒併發同步之Semaphore
概念 Semaphore是一種在多執行緒環境下使用的設施,該設施負責協調各個執行緒,用來管理資源,以保證它們能夠正確、合理的使用公共資源的設施,也是作業系統中用於控制程序同步互斥的量。用我們常見的說法就是用來控制併發數。 訊號量是一個非負整數 。 業務場景 以售
Java多執行緒/併發20、Future實現類:FutureTask
FutureTask是future的實現類,它同時實現了兩個介面:Runnable和Future,所以它既可以作為Runnable被執行緒執行,又可以作為Future得到Callable的返回值。 因此我們可以: - 呼叫FutureTask物件的ru
二、Java多執行緒併發同步之CyclicBarrier
概述 CyclicBarrier:可迴圈屏障,允許一組執行緒全部等待的同步輔助工具。一組執行緒互相等待,直到所有執行緒都到達某個公共屏障點(也可以叫同步點) 。它可以在等待執行緒之後重新使用。這個屏障之所以用迴圈修飾,是因為在所有的執行緒釋放彼此之後,這個屏障是
java多執行緒併發系列之閉鎖(Latch)和柵欄(CyclicBarrier)
-閉鎖(Latch) 閉鎖(Latch):一種同步方法,可以延遲執行緒的進度直到執行緒到達某個終點狀態。通俗的講就是,一個閉鎖相當於一扇大門,在大門開啟之前所有執行緒都被阻斷,一旦大門開啟所有執行緒都將通過,但是一旦大門開啟,所有執行緒都通過了,那麼這個閉鎖的狀態就失效了,門
入坑JAVA多執行緒併發(六)死鎖
在多執行緒的中,因為要保證執行緒安全,需要對一些操作進行加鎖,但是如果操作不當,會造成死鎖,導致程式無法執行下去。 形成死鎖的場景:如果有兩個執行緒,執行緒1和執行緒2,執行緒1執行,獲得鎖A,執行緒2執行,獲得B,執行緒1等待鎖B的釋放,執行緒2等待
入坑JAVA多執行緒併發(五)生產者消費者模式
生產者消費者模式對於理解多執行緒是一個很經典,也很好的例子 資源類: class Resource{ //資源初始化個數 private int init; //資源最大個數 private int Max; p
入坑JAVA多執行緒併發(二)執行緒的生命週期和常用方法
執行緒的生命週期大致分為五種狀態: 1. 新建: 新建一個執行緒物件。 2.可執行: 啟動執行緒,呼叫start方法或者呼叫執行緒池的excute方法等,此時執行緒會進入可執行執行緒池中,等待獲取CPU的時間片。 3.執行 執行狀態,也就
Java多執行緒併發最佳實踐
使用本地變數 儘量使用本地變數,而不是建立一個類或例項的變數。 使用不可變類 String、Integer等。不可變類可以降低程式碼中需要的同步數量。 最小化鎖的作用域範圍:S=1/(1-a+a/n) a:平行計算部分所佔比例 n:並行處理結點個數 S:加速比 當1-a等於0時,沒有序列只有並
入坑JAVA多執行緒併發(八)詳解ThreadLocal使用和原理
ThreadLocal是一個用於儲存多執行緒變數的類,它可以把執行緒與設定的值對應起來,因為它為變數在每個執行緒都建立了一個副本。訪問的時候每個執行緒只能訪問到自己的副本變數。 例項 看如下程式碼: public class Main {
入坑JAVA多執行緒併發(四)賣火車票瞭解一下
多執行緒最常用的兩個例子就是:火車票和生產者消費者問題了,本文簡單的實現一下賣火車票的例子, 首先建立車票類: class Ticket implements Runnable{ private int num; private int
入坑JAVA多執行緒併發(九)CAS和ABA
如果瞭解資料庫的悲觀鎖和樂觀鎖的話,對於理解CAS就很簡單了,因為CAS就是樂觀鎖的具體實現。 悲觀鎖:在操作資料庫時本能的覺得一定會有競爭,所以把資料鎖住,不讓其他事物對對應的資料進行操作,在本次操作之後把鎖釋放,其它事物才可以進行操作。這個在jav