国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

zzzmh / 554人閱讀

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

【條件競爭

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

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

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

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

synchronized關(guān)鍵字。

Reentrantlock類。

【synchronized關(guān)鍵字

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

不能中斷正在試圖獲得鎖的線程。

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

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

【多個(gè)線程修改同一個(gè)對象造成數(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()));
            //等待子線程執(zhí)行完畢
            CompletableFuture.allOf(cfs.toArray(new CompletableFuture[cfs.size()])).join();
            System.out.println(s.getValue());
        }
    }
}

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

【注意

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

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

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

public class Account {
    //賬戶金額
    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("錢不夠了!");
        }
        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)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/68094.html

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

    dingding199389 評論0 收藏0

發(fā)表評論

0條評論

zzzmh

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<