java 并發(fā)中的原子性與可視性實例詳解
java 并發(fā)中的原子性與可視性實例詳解
并發(fā)其實是一種解耦合的策略,它幫助我們把做什么(目標)和什么時候做(時機)分開。這樣做可以明顯改進應(yīng)用程序的吞吐量(獲得更多的CPU調(diào)度時間)和結(jié)構(gòu)(程序有多個部分在協(xié)同工作)。做過java Web開發(fā)的人都知道,Java Web中的Servlet程序在Servlet容器的支持下采用單實例多線程的工作模式,Servlet容器為你處理了并發(fā)問題。
原子性
原子是世界上的最小單位,具有不可分割性。比如 a=0;(a非long和double類型) 這個操作是不可分割的,那么我們說這個操作時原子操作。再比如:a++; 這個操作實際是a = a + 1;是可分割的,所以他不是一個原子操作。非原子操作都會存在線程安全問題,需要我們使用同步技術(shù)(sychronized)來讓它變成一個原子操作。一個操作是原子操作,那么我們稱它具有原子性。Java的concurrent包下提供了一些原子類,我們可以通過閱讀API來了解這些原子類的用法。比如:AtomicInteger、AtomicLong、AtomicReference等。
可見性
可見性,是指線程之間的可見性,一個線程修改的狀態(tài)對另一個線程是可見的。也就是一個線程修改的結(jié)果。另一個線程馬上就能看到。比如:用volatile修飾的變量,就會具有可見性。volatile修飾的變量不允許線程內(nèi)部緩存和重排序,即直接修改內(nèi)存。所以對其他線程是可見的。但是這里需要注意一個問題,volatile只能讓被他修飾內(nèi)容具有可見性,但不能保證它具有原子性。比如 volatile int a = 0;之后有一個操作 a++;這個變量a具有可見性,但是a++ 依然是一個非原子操作,也就這這個操作同樣存在線程安全問題。
他們之間關(guān)系
原子性是說一個操作是否可分割??梢娦允钦f操作結(jié)果其他線程是否可見。這么看來他們其實沒有什么關(guān)系。
實例
package com.chu.test.thread; /** * 可見性分析 * @author Administrator * *volatile 會拒絕編譯器對其修飾的變量進行優(yōu)化。也就不會存在重排序的問題。volatile只會影響可見性,不會影響原子性。 *下面程序如果不加 */ public class Test { volatile int a = 1; volatile boolean ready; public class PrintA extends Thread{ @Override public void run() { while(!ready){ Thread.yield(); } System.out.println(a); } } public static void main(String[] args) throws InterruptedException { Test t = new Test(); t.new PrintA().start(); //下面兩行如果不加volatile的話,執(zhí)行的先后順序是不可預(yù)測的。并且下面兩行都是原子操作,但是這兩行作為一個整體的話就不是一個原子操作。 t.a = 48; //這是一個原子操作,但是其結(jié)果不一定具有可見性。加上volatile后就具備了可見性。 t.ready = true;//同理 } }
上面程序如果變量a不用volatile修飾那么輸出結(jié)果很可能就是0.。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
相關(guān)文章
SpringMVC使用MultipartResolver實現(xiàn)文件上傳
MultipartResolver 用于處理文件上傳,當收到請求時 DispatcherServlet 的 checkMultipart() 方法會調(diào)用 MultipartResolver 的 isMultipart() 方法判斷請求中是否包含文件2023-02-02java冷知識:javac AbstractProcessor詳解
這篇文章主要介紹了java冷知識:javac AbstractProcessor詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11SpringBoot項目請求不中斷動態(tài)更新代碼的實現(xiàn)
在開發(fā)中,有時候不停機動態(tài)更新代碼熱部署是一項至關(guān)重要的功能,它可以在請求不中斷的情況下下更新代碼,這種方式不僅提高了開發(fā)效率,還能加速測試和調(diào)試過程,本文將詳細介紹如何在 Spring Boot 項目在Linux系統(tǒng)中實現(xiàn)熱部署,特別關(guān)注優(yōu)雅關(guān)閉功能的實現(xiàn)2024-09-09利用Mybatis向PostgreSQL中插入并查詢JSON字段
這篇文章主要介紹了利用Mybatis向PostgreSQL中插入并查詢JSON字段,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-07-07