亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

java并發(fā)編程學(xué)習(xí)7--同步--synchronized關(guān)鍵字

zzzmh / 602人閱讀

摘要:如果兩個(gè)線(xiàn)程存取相同的對(duì)象,并且每一個(gè)線(xiàn)程都調(diào)用一個(gè)修改該對(duì)象狀態(tài)的方法,根據(jù)線(xiàn)程訪(fǎng)問(wèn)數(shù)據(jù)的順序,可能會(huì)出現(xiàn)錯(cuò)誤的數(shù)據(jù)結(jié)果,這種現(xiàn)象成為條件競(jìng)爭(zhēng)。而問(wèn)題往往就是有多個(gè)線(xiàn)程同時(shí)在執(zhí)行步驟。內(nèi)部鎖有如下的特點(diǎn)不能中斷正在試圖獲得鎖的線(xiàn)程。

【條件競(jìng)爭(zhēng)

在多線(xiàn)程的開(kāi)發(fā)中,兩個(gè)及其以上的線(xiàn)程需要共享統(tǒng)一數(shù)據(jù)的存取。如果兩個(gè)線(xiàn)程存取相同的對(duì)象,并且每一個(gè)線(xiàn)程都調(diào)用一個(gè)修改該對(duì)象狀態(tài)的方法,根據(jù)線(xiàn)程訪(fǎng)問(wèn)數(shù)據(jù)的順序,可能會(huì)出現(xiàn)錯(cuò)誤的數(shù)據(jù)結(jié)果,這種現(xiàn)象成為條件競(jìng)爭(zhēng)。因?yàn)樾薷膶?duì)象狀態(tài)的方法并不是一個(gè)原子操作,通常步驟是:

1. 讀取當(dāng)前狀態(tài)值到線(xiàn)程工作內(nèi)存。
2. 在線(xiàn)程工作內(nèi)存中修改狀態(tài)值。
3. 將修改后的狀態(tài)值重新寫(xiě)入主內(nèi)存。

而問(wèn)題往往就是有多個(gè)線(xiàn)程同時(shí)在執(zhí)行步驟2。

【 有兩種機(jī)制代碼受并發(fā)訪(fǎng)問(wèn)的干擾

synchronized關(guān)鍵字。

Reentrantlock類(lèi)。

【synchronized關(guān)鍵字

java中每個(gè)對(duì)象都有一個(gè)內(nèi)部鎖。如果一個(gè)方法是用synchronized關(guān)鍵字修聲明的,那么對(duì)象的鎖將保護(hù)整個(gè)方法,也就是說(shuō)要調(diào)用該方法,線(xiàn)程必須獲得對(duì)象內(nèi)部鎖。內(nèi)部鎖有如下的特點(diǎn):

不能中斷正在試圖獲得鎖的線(xiàn)程。

試圖獲得鎖不能設(shè)置超時(shí)時(shí)間。

只有一個(gè)條件:要么獲得,要么等待,沒(méi)有粒度更細(xì)的控制。

【多個(gè)線(xiàn)程修改同一個(gè)對(duì)象造成數(shù)據(jù)失誤
public class Sync {

    private int value;

    void add(){
        this.value ++;
    }
    int getValue(){
        return this.value;
    }

    public static void main(String[] args) {
        for (int i = 0; i <30 ; i++) {
            Sync s = new Sync();
            List cfs = new ArrayList<>();
            cfs.add(CompletableFuture.runAsync(() -> s.add()));
            cfs.add(CompletableFuture.runAsync(() -> s.add()));
            cfs.add(CompletableFuture.runAsync(() -> s.add()));
            //等待子線(xiàn)程執(zhí)行完畢
            CompletableFuture.allOf(cfs.toArray(new CompletableFuture[cfs.size()])).join();
            System.out.println(s.getValue());
        }
    }
}

現(xiàn)在使用synchronized關(guān)鍵字修飾add()看看:數(shù)據(jù)正常。

【注意

如果我們?cè)谕降臅r(shí)候需要判斷,切記將條件判斷放在同步代碼塊之中,如果在外部判斷,很有可能出現(xiàn):

1. 第一個(gè)線(xiàn)程通過(guò)條件判斷
2. 第二個(gè)線(xiàn)程獲得cpu,并修改了共享對(duì)象
3. 第一個(gè)線(xiàn)程再次獲得cpu此時(shí)已經(jīng)不滿(mǎn)足條件,但是代碼在向下執(zhí)行,于是出現(xiàn)異常的情況。

例如轉(zhuǎn)賬的例子:

public class Account {
    //賬戶(hù)金額
    private int amount;

    public Account(int amount){
        this.amount = amount;
    }

    //轉(zhuǎn)賬
    public synchronized void trans(Account to,int value){
        //條件判斷處于同步代碼中?。。。。?!
        if(amount - value < 0){
            throw new RuntimeException("錢(qián)不夠了!");
        }
        this.amount -= value;
        to.addAmount(value);
        System.out.println("轉(zhuǎn)賬成功");
    }

    public void addAmount(int amount){
        this.amount += amount;
    }
    public int getAmount(){
        return this.amount;
    }

    public static void main(String[] args) {
        Account from = new Account(100);
        Account to1 = new Account(0);
        Account to2 = new Account(0);
        List cfs = new ArrayList<>();
        cfs.add(CompletableFuture.runAsync(() -> from.trans(to1,100)));
        cfs.add(CompletableFuture.runAsync(() -> from.trans(to2,100)));
        CompletableFuture.allOf(cfs.toArray(new CompletableFuture[cfs.size()])).join();
        System.out.println(from.getAmount());
        System.out.println(to1.getAmount());
        System.out.println(to2.getAmount());
    }
}

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/68094.html

相關(guān)文章

  • 并發(fā)編程的藝術(shù)

    摘要:假設(shè)不發(fā)生編譯器重排和指令重排,線(xiàn)程修改了的值,但是修改以后,的值可能還沒(méi)有寫(xiě)回到主存中,那么線(xiàn)程得到就是很自然的事了。同理,線(xiàn)程對(duì)于的賦值操作也可能沒(méi)有及時(shí)刷新到主存中。線(xiàn)程的最后操作與線(xiàn)程發(fā)現(xiàn)線(xiàn)程已經(jīng)結(jié)束同步。 很久沒(méi)更新文章了,對(duì)隔三差五過(guò)來(lái)刷更新的讀者說(shuō)聲抱歉。 關(guān)于 Java 并發(fā)也算是寫(xiě)了好幾篇文章了,本文將介紹一些比較基礎(chǔ)的內(nèi)容,注意,閱讀本文需要一定的并發(fā)基礎(chǔ)。 本文的...

    curlyCheng 評(píng)論0 收藏0
  • java并發(fā)編程學(xué)習(xí)13--Atomic數(shù)據(jù)結(jié)構(gòu)簡(jiǎn)介

    摘要:介紹中無(wú)鎖的線(xiàn)程安全整數(shù),一個(gè)提供原子操作的的類(lèi)。在語(yǔ)言中,和操作并不是線(xiàn)程安全的,在使用的時(shí)候,不可避免的會(huì)用到關(guān)鍵字。而則通過(guò)一種線(xiàn)程安全的加減操作接口。就是的意思,比較并操作。有個(gè)操作數(shù),內(nèi)存值,舊的預(yù)期值,要修改的新值。 【介紹 JAVA 中無(wú)鎖的線(xiàn)程安全整數(shù) AtomicInteger,一個(gè)提供原子操作的Integer的類(lèi)。在Java語(yǔ)言中,++i和i++操作并不是線(xiàn)程安全的...

    李增田 評(píng)論0 收藏0
  • java并發(fā)編程學(xué)習(xí)1--基礎(chǔ)知識(shí)

    摘要:死亡狀態(tài)線(xiàn)程退出有可能是正常執(zhí)行完成也有可能遇見(jiàn)異常退出。類(lèi)有新建與死亡狀態(tài)返回其余狀態(tài)返回判斷線(xiàn)程是否存活。線(xiàn)程因某些原因進(jìn)入阻塞狀態(tài)。執(zhí)行同步代碼塊的過(guò)程中執(zhí)行了當(dāng)前線(xiàn)程放棄開(kāi)始睡眠進(jìn)入就緒狀態(tài)但是不會(huì)釋放鎖。 【java內(nèi)存模型簡(jiǎn)介 JVM中存在一個(gè)主存區(qū)(Main Memory或Java Heap Memory),Java中所有變量都是存在主存中的,對(duì)于所有線(xiàn)程進(jìn)行共享,而每個(gè)...

    huangjinnan 評(píng)論0 收藏0
  • Java多線(xiàn)程學(xué)習(xí)(三)volatile關(guān)鍵字

    摘要:三關(guān)鍵字能保證原子性嗎并發(fā)編程藝術(shù)這本書(shū)上說(shuō)保證但是在自增操作非原子操作上不保證,多線(xiàn)程編程核心藝術(shù)這本書(shū)說(shuō)不保證。多線(xiàn)程訪(fǎng)問(wèn)關(guān)鍵字不會(huì)發(fā)生阻塞,而關(guān)鍵字可能會(huì)發(fā)生阻塞關(guān)鍵字能保證數(shù)據(jù)的可見(jiàn)性,但不能保證數(shù)據(jù)的原子性。 系列文章傳送門(mén): Java多線(xiàn)程學(xué)習(xí)(一)Java多線(xiàn)程入門(mén) Java多線(xiàn)程學(xué)習(xí)(二)synchronized關(guān)鍵字(1) java多線(xiàn)程學(xué)習(xí)(二)synchroniz...

    tain335 評(píng)論0 收藏0
  • Java多線(xiàn)程學(xué)習(xí)(七)并發(fā)編程中一些問(wèn)題

    摘要:相比與其他操作系統(tǒng)包括其他類(lèi)系統(tǒng)有很多的優(yōu)點(diǎn),其中有一項(xiàng)就是,其上下文切換和模式切換的時(shí)間消耗非常少。因?yàn)槎嗑€(xiàn)程競(jìng)爭(zhēng)鎖時(shí)會(huì)引起上下文切換。減少線(xiàn)程的使用。很多編程語(yǔ)言中都有協(xié)程。所以如何避免死鎖的產(chǎn)生,在我們使用并發(fā)編程時(shí)至關(guān)重要。 系列文章傳送門(mén): Java多線(xiàn)程學(xué)習(xí)(一)Java多線(xiàn)程入門(mén) Java多線(xiàn)程學(xué)習(xí)(二)synchronized關(guān)鍵字(1) java多線(xiàn)程學(xué)習(xí)(二)syn...

    dingding199389 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

zzzmh

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<