java 并發(fā)中的原子性與可視性實(shí)例詳解
java 并發(fā)中的原子性與可視性實(shí)例詳解
并發(fā)其實(shí)是一種解耦合的策略,它幫助我們把做什么(目標(biāo))和什么時(shí)候做(時(shí)機(jī))分開(kāi)。這樣做可以明顯改進(jìn)應(yīng)用程序的吞吐量(獲得更多的CPU調(diào)度時(shí)間)和結(jié)構(gòu)(程序有多個(gè)部分在協(xié)同工作)。做過(guò)java Web開(kāi)發(fā)的人都知道,Java Web中的Servlet程序在Servlet容器的支持下采用單實(shí)例多線(xiàn)程的工作模式,Servlet容器為你處理了并發(fā)問(wèn)題。
原子性
原子是世界上的最小單位,具有不可分割性。比如 a=0;(a非long和double類(lèi)型) 這個(gè)操作是不可分割的,那么我們說(shuō)這個(gè)操作時(shí)原子操作。再比如:a++; 這個(gè)操作實(shí)際是a = a + 1;是可分割的,所以他不是一個(gè)原子操作。非原子操作都會(huì)存在線(xiàn)程安全問(wèn)題,需要我們使用同步技術(shù)(sychronized)來(lái)讓它變成一個(gè)原子操作。一個(gè)操作是原子操作,那么我們稱(chēng)它具有原子性。Java的concurrent包下提供了一些原子類(lèi),我們可以通過(guò)閱讀API來(lái)了解這些原子類(lèi)的用法。比如:AtomicInteger、AtomicLong、AtomicReference等。
可見(jiàn)性
可見(jiàn)性,是指線(xiàn)程之間的可見(jiàn)性,一個(gè)線(xiàn)程修改的狀態(tài)對(duì)另一個(gè)線(xiàn)程是可見(jiàn)的。也就是一個(gè)線(xiàn)程修改的結(jié)果。另一個(gè)線(xiàn)程馬上就能看到。比如:用volatile修飾的變量,就會(huì)具有可見(jiàn)性。volatile修飾的變量不允許線(xiàn)程內(nèi)部緩存和重排序,即直接修改內(nèi)存。所以對(duì)其他線(xiàn)程是可見(jiàn)的。但是這里需要注意一個(gè)問(wèn)題,volatile只能讓被他修飾內(nèi)容具有可見(jiàn)性,但不能保證它具有原子性。比如 volatile int a = 0;之后有一個(gè)操作 a++;這個(gè)變量a具有可見(jiàn)性,但是a++ 依然是一個(gè)非原子操作,也就這這個(gè)操作同樣存在線(xiàn)程安全問(wèn)題。
他們之間關(guān)系
原子性是說(shuō)一個(gè)操作是否可分割??梢?jiàn)性是說(shuō)操作結(jié)果其他線(xiàn)程是否可見(jiàn)。這么看來(lái)他們其實(shí)沒(méi)有什么關(guān)系。
實(shí)例
package com.chu.test.thread;
/**
* 可見(jiàn)性分析
* @author Administrator
*
*volatile 會(huì)拒絕編譯器對(duì)其修飾的變量進(jìn)行優(yōu)化。也就不會(huì)存在重排序的問(wèn)題。volatile只會(huì)影響可見(jiàn)性,不會(huì)影響原子性。
*下面程序如果不加
*/
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的話(huà),執(zhí)行的先后順序是不可預(yù)測(cè)的。并且下面兩行都是原子操作,但是這兩行作為一個(gè)整體的話(huà)就不是一個(gè)原子操作。
t.a = 48; //這是一個(gè)原子操作,但是其結(jié)果不一定具有可見(jiàn)性。加上volatile后就具備了可見(jiàn)性。
t.ready = true;//同理
}
}
上面程序如果變量a不用volatile修飾那么輸出結(jié)果很可能就是0.。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
java正則匹配讀取txt文件提取特定開(kāi)頭和結(jié)尾的字符串
通常我們可以直接通過(guò)文件流來(lái)讀取txt文件的內(nèi)容,但有時(shí)候也會(huì)遇到問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于java正則匹配讀取txt文件提取特定開(kāi)頭和結(jié)尾的字符串的相關(guān)資料,需要的朋友可以參考下2022-11-11
Java時(shí)間類(lèi)庫(kù)Timer的使用方法與實(shí)例詳解
這篇文章主要介紹了Jave時(shí)間類(lèi)庫(kù)Timer的使用方法與實(shí)例詳解,需要的朋友可以參考下2020-02-02
JavaSE程序邏輯控制實(shí)現(xiàn)詳細(xì)圖文教程
JavaSE是為了開(kāi)發(fā)桌面應(yīng)用程序和控制臺(tái)應(yīng)用程序而設(shè)計(jì)的,使用JavaSE可以編寫(xiě)?yīng)毩⑦\(yùn)行的Java應(yīng)用程序,這篇文章主要給大家介紹了關(guān)于JavaSE程序邏輯控制實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2024-04-04
SpringMVC 參數(shù)綁定相關(guān)知識(shí)總結(jié)
這篇文章主要介紹了SpringMVC 參數(shù)綁定相關(guān)知識(shí)總結(jié),幫助大家更好的理解和學(xué)習(xí)使用SpringMVC,感興趣的朋友可以了解下2021-03-03
springboot2.6.4集成swagger3.0遇到的坑及解決方法
這篇文章主要介紹了springboot2.6.4如何集成swagger3.0,在集成的過(guò)程中遇到很多問(wèn)題,本文給大家分享四種問(wèn)題及相應(yīng)的解決方案,需要的朋友可以參考下2022-03-03
SpringBoot配置主從數(shù)據(jù)庫(kù)實(shí)現(xiàn)讀寫(xiě)分離
現(xiàn)在的 Web 應(yīng)用大都是讀多寫(xiě)少,本文主要介紹了SpringBoot配置主從數(shù)據(jù)庫(kù)實(shí)現(xiàn)讀寫(xiě)分離,具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11
springcloud gateway自定義斷言規(guī)則詳解,以后綴結(jié)尾進(jìn)行路由
這篇文章主要介紹了springcloud gateway自定義斷言規(guī)則詳解,以后綴結(jié)尾進(jìn)行路由,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
關(guān)于mybatis resulttype 返回值異常的問(wèn)題
這篇文章主要介紹了mybatis resulttype 返回值異常的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
簡(jiǎn)單理解遵循接口隔離原則的Java設(shè)計(jì)模式編程
這篇文章主要介紹了遵循接口隔離原則的Java設(shè)計(jì)模式編程,針對(duì)Java編程中interface接口方面的編寫(xiě)進(jìn)行約束,需要的朋友可以參考下2016-02-02

