中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

如何結(jié)局線程安全問題-創(chuàng)新互聯(lián)

什么是線程安全問題?

當(dāng)多個線程共享一個全局變量,對其做寫操作時,可能會受到其他線程的干擾,從而引發(fā)線程安全問題

創(chuàng)新互聯(lián)建站-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比安塞網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式安塞網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋安塞地區(qū)。費用合理售后完善,十載實體公司更值得信賴。

內(nèi)置鎖(synchronized)

內(nèi)置鎖也叫互斥鎖,可以保證線程的原子性,當(dāng)線程進入方法時,會自動獲得一個鎖,一旦鎖被獲得,其他線程必須等待獲得鎖的線程執(zhí)行完代碼釋放鎖,會降低程序的執(zhí)行效率

使用方式:

同步方法

public synchronized void sale() {
    if (trainCount > 0) {
        System.out.println(Thread.currentThread().getName() + "票" + (100 - trainCount + 1) + "張票");
        trainCount --;
    }
}
// 非靜態(tài)同步方法使用this鎖
// 靜態(tài)同步方法使用當(dāng)前字節(jié)碼文件

同步代碼塊

private Object obj = new Object();
....
public void sale() {
    // 參數(shù)為任意全局對象
    synchronized (obj) {
        if (trainCount > 0) {
            System.out.println(Thread.currentThread().getName() + "票" + (100 - trainCount + 1) + "張票");
            trainCount --;
        }
    }
}

注意事項:

public static void main(String[] args) {
    ThreadDemo1 threadDemo1 = new ThreadDemo1();
    ThreadDemo1 threadDemo2 = new ThreadDemo1();
    Thread t1 = new Thread(threadDemo1, "窗口1");
    Thread t2 = new Thread(threadDemo2, "窗口2");
    t1.start();
    t2.start();
}
// 這樣的話也會產(chǎn)生線程安全問題
// 那是因為兩個線程分別由不同的線程創(chuàng)建的,它們之間的變量不共享,產(chǎn)生了兩把不同的鎖
// 解決方法是在全局變量上加上 static 關(guān)鍵字,靜態(tài)變量存在方法區(qū),這個類中的所有對象都共享同一個變量

重入鎖和不可重入鎖

重入鎖:即獲得鎖的線程可以進入它擁有的鎖的同步代碼塊

不可重入鎖:即獲得鎖的線程,在方法中嘗試再次獲得鎖時,獲取不到進入阻塞狀態(tài)

死鎖產(chǎn)生的原因

同步中嵌套同步,同步鎖是一個重入鎖,就很有可能發(fā)生死鎖

ThreadLocal

為每個線程提供局部變量,解決線程安全問題

ThreadLocal 底層采用 Map 來實現(xiàn),將當(dāng)前線程作為key,將值存儲到這個 map 中

class Res {
    private Integer count = 0;
    ThreadLocal<Integer> integerThreadLocal = new ThreadLocal<Integer>() {
        @Override
        protected Integer initialValue() {
            return 0;
        }
    };

    public Integer getCount() {
        int count = integerThreadLocal.get() + 1;
        integerThreadLocal.set(count);
        return count;
    }
}

多線性特性

什么是原子性?

即一個或一組操作,要么全部執(zhí)行,執(zhí)行過程中不會被其他線程打斷,要么全部不執(zhí)行

什么是可見性?

多線程操作中一個線程修改了全局共享變量的值,其他線程能立馬得到修改后的值

什么是有序性?

程序執(zhí)行的順序按照代碼的先后順序執(zhí)行,一般來說處理器為了提高程序運行效率,可能會對輸入代碼進行優(yōu)化,它不保證程序中各個語句的執(zhí)行先后順序同代碼中的順序一致,但是它會保證程序最終執(zhí)行結(jié)果和代碼順序執(zhí)行的結(jié)果是一致的

Java 內(nèi)存模型(JMM)

JMM 決定一個線程對一個共享變量做寫操作時,能否對另一個線程可見

主內(nèi)存:共享變量

本地內(nèi)存:共享變量副本

多線程做修改操作時,首先從主內(nèi)存中拷貝一份副本到本地內(nèi)存中,當(dāng)線程修改本地內(nèi)存的值后,首先在本地內(nèi)存修改成功,然后再將修改后的結(jié)果刷新到主內(nèi)存中

Volatile

可見性就是說一旦某個線程修改了被 Volatile 修飾的變量,其他線程能立馬獲取到修改后的新值,在 Java 中為了加快程序的運行效率,對一些變量的操作通常是在該線程的寄存器或者 CPU 緩存中進行的,之后才會同步到主存,而加了 Volatile 關(guān)鍵字后會直接讀寫內(nèi)存

注意:雖然該關(guān)鍵字能夠保證可見性,但不能保證原子性

特性:

  • 保證可見性
  • 禁止指令重排(CPU采用了允許將多條指令不按程序規(guī)定的順序分開發(fā)送給各相應(yīng)電路單元處理),使用Volatile 修飾的變量,賦值后多執(zhí)行了一個"load addl $0x0, (%esp)"操作,這個操作相當(dāng)于一個內(nèi)存屏障(指令重排序時不能把后面的指令重排序到內(nèi)存屏障之前的位置),只有一個CPU訪問內(nèi)存時,并不需要內(nèi)存屏障。

Volatile 與 Synchronized 區(qū)別:

Volatile 雖然能保證可見性,但不能保證原子性

Synchronized 防止多個線程執(zhí)行同一塊代碼,影響執(zhí)行效率,就性能而言,Volatile 是高于 Synchronized 的。

但是 Volatile 是不能取代 Synchronized 的,因為 Volatile 不能保證原子性。

重排序

數(shù)據(jù)依賴

如果兩個操作同時操作一份變量,且這兩個操作其中有一個寫操作,此時這兩個操作之間就存在數(shù)據(jù)依賴

名稱代碼示例說明
寫后讀a = 1;b = a;寫一個變量之后,再讀這個位置。
寫后寫a = 1;a = 2;寫一個變量之后,再寫這個變量。
讀后寫a = b;b = 1;讀一個變量之后,再寫這個變量

上面三種情況,只要更改操作的執(zhí)行順序,結(jié)果就會發(fā)生改變,編譯器和處理器可能會做重排序,在做重排序時會尊徐數(shù)據(jù)依賴,所以編譯器和處理器不能對數(shù)據(jù)依賴的操作重排序,這里的數(shù)據(jù)依賴性僅針對單個處理器中執(zhí)行的指令序列和單線程的操作,不同處理器之間和不同線程之間的數(shù)據(jù)依賴性不被編譯器和處理器考慮

as-if-serial語義

不管怎么重排,結(jié)果都不能改變

對多線程的影響

在單線程程序中,對存在數(shù)據(jù)依賴的操作做重排序不會影響結(jié)果,因為單線程尊徐 as-if-serial 語義,但 as-if-serial 語義提到"不考慮不同處理器之間和不同線程之間的數(shù)據(jù)依賴",所以,指令重排可能會對多線程的結(jié)果產(chǎn)生影響

創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國云服務(wù)器,動態(tài)BGP最優(yōu)骨干路由自動選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機房獨有T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動現(xiàn)已開啟,新人活動云服務(wù)器買多久送多久。

標(biāo)題名稱:如何結(jié)局線程安全問題-創(chuàng)新互聯(lián)
文章出自:http://www.rwnh.cn/article30/pcgpo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、網(wǎng)站設(shè)計品牌網(wǎng)站設(shè)計、軟件開發(fā)、品牌網(wǎng)站建設(shè)、用戶體驗

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作
丹寨县| 嘉定区| 文昌市| 安仁县| 巴中市| 清远市| 河曲县| 扎赉特旗| 通州市| 长治县| 连云港市| 辉南县| 铜鼓县| 泗水县| 万年县| 和龙市| 广元市| 泗洪县| 疏勒县| 长寿区| 谷城县| 临汾市| 嘉兴市| 会理县| 安乡县| 永州市| 东安县| 双江| 乌兰察布市| 盘山县| 娱乐| 泸西县| 民勤县| 阿拉善右旗| 永顺县| 永德县| 六盘水市| 资讯| 丽水市| 平阳县| 花莲市|