成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Java 并發(fā)編程系列之帶你了解多線程

Elle / 3501人閱讀

摘要:的內(nèi)置鎖是一種互斥鎖,意味著最多只有一個線程能持有這種鎖。使用方式如下使用顯示鎖之前,解決多線程共享對象訪問的機(jī)制只有和。后面會陸續(xù)的補(bǔ)充并發(fā)編程系列的文章。

早期的計算機(jī)不包含操作系統(tǒng),它們從頭到尾執(zhí)行一個程序,這個程序可以訪問計算機(jī)中的所有資源。在這種情況下,每次都只能運(yùn)行一個程序,對于昂貴的計算機(jī)資源來說是一種嚴(yán)重的浪費(fèi)。

操作系統(tǒng)出現(xiàn)后,計算機(jī)可以運(yùn)行多個程序,不同的程序在多帶帶的進(jìn)程中運(yùn)行。操作系統(tǒng)負(fù)責(zé)為各個獨立的進(jìn)程分配各種資源。并且不同的進(jìn)程間可以通過一些通信機(jī)制來交換數(shù)據(jù),比如:套接字、信號處理器、共享內(nèi)存、信號量等。

一、了解多線程

1.1 進(jìn)程與線程

想必大家都聽說過這兩個名詞,它們之間有什么聯(lián)系與不同呢?

記得當(dāng)時上操作系統(tǒng)課時,書上有這么一句話:進(jìn)程是獨立擁有 cpu 資源的最 小單位,線程是接受 cpu 調(diào)度的最小單位。網(wǎng)上看了那么多的解釋,還是覺得書上說的最簡單明了。

進(jìn)程中可以同時存在多個程序控制流程的線程,線程會共享進(jìn)程范圍內(nèi)的資源,因此一個進(jìn)程可以有多個線程。打個比方,進(jìn)程就像一個大工廠,而線程就是工廠的工人,多個工人負(fù)責(zé)協(xié)同完成工廠的任務(wù)。

1.2 多線程的優(yōu)勢

發(fā)揮多處理器的強(qiáng)大能力

簡化建模過程

簡化異步事件處理機(jī)制

響應(yīng)更靈敏的用戶界面

1.3 多線程安全性問題

多線程是一把雙刃劍,使用多線程時意味著對開發(fā)人員有一定的技術(shù)要求??梢妼W(xué)會了多線程技術(shù),就能寫出更優(yōu)雅的代碼了,哈哈~

多個線程同時訪問意味著“共享”變量,這些“共享”變量往往在其生命周期內(nèi)是可變的,這樣以來就極易出現(xiàn)多線程安全性問題。

什么是線程安全,這里給一個比較準(zhǔn)確的定義:當(dāng)多個線程訪問某各類時,這個類始終都能表現(xiàn)出正確的行為,那么就稱這個類是線程安全的。

二、Java 內(nèi)存模型

為什么要在多線程專題里涉及到 Java 內(nèi)存模型呢?我覺得它可以幫助我們更好的理解多線程的工作機(jī)制。

比如很多人都聽說過或了解過 volatile 關(guān)鍵字,都知道它能保證內(nèi)存可見性問題,但是理解起來總是太過抽象。如果你了解了 Java 內(nèi)存模型,它可以很好的幫助你理解這些問題。

Java 內(nèi)存模型規(guī)定了所有的變量都存儲在主內(nèi)存中(Main Memory)中(可以類比為物理硬件的主內(nèi)存)。每條線程都有自己的工作內(nèi)存(Working Memory),線程的工作內(nèi)存中保存了主內(nèi)存中的變量的拷貝,線程對變量的所有操作(讀取、賦值)都必須在自己的工作內(nèi)存中進(jìn)行,而不能直接讀寫主內(nèi)存中的變量。

不同的線程之間無法訪問對方工作內(nèi)存中的變量,線程間變量值的傳遞均需要通過主內(nèi)存來完成。

如果你對 Java 內(nèi)存區(qū)域了解的話,很容易就會想工作內(nèi)存、主內(nèi)存與 Java 內(nèi)存區(qū)域中的堆、棧、方法區(qū)是否有一定關(guān)系呢?

如果在實例變量的角度來看,主內(nèi)存對應(yīng)于 Java 堆中的對象實例數(shù)據(jù)部分,而工作內(nèi)存則對應(yīng)于虛擬機(jī)棧中的部分區(qū)域。從更低層次來看,主內(nèi)存直接對應(yīng)于物理硬件的內(nèi)存。

三、解決線程安全性問題

使用 Java 創(chuàng)建線程的幾種方式這里就不再贅述了,我們來了解幾種處理多線程安全性問題的方法。

3.1 synchronized 關(guān)鍵字

Java 提供了一種內(nèi)置的鎖機(jī)制(synchronized 關(guān)鍵字)來保證原子性與內(nèi)存可見性。關(guān)于原子性與內(nèi)存可見性問題會在講述 volatile 關(guān)鍵字時詳細(xì)的介紹,感興趣的可以關(guān)注后面的文章。

Java 的內(nèi)置鎖是一種互斥鎖,意味著最多只有一個線程能持有這種鎖。當(dāng)線程 A 和線程 B 同時訪問臨界資源,如果線程 A 獲取鎖,線程 B 就必須等待或阻塞,A 不釋放 B 就只能等待下去。

由于每次只有一個線程執(zhí)行內(nèi)置鎖內(nèi)的代碼,因此被 synchronized 關(guān)鍵字保護(hù)的臨界資源會以原子(一組不可分割的單元)的方式執(zhí)行,多個線程間執(zhí)行時不會受到干擾,原子性與數(shù)據(jù)庫事務(wù)有相同的含義。

synchronized 關(guān)鍵字可以用來修飾方法和代碼塊,如果修飾非靜態(tài)方法和同步代碼塊,使用的鎖是當(dāng)前對象,如果修飾靜態(tài)方法和靜態(tài)代碼塊,使用的是當(dāng)前類的 Class 對象作為鎖。

使用方式如下

public class SyncTest {
    private Integer num = 1;
    
    public int numAutoIncrement() {
        synchronized (this) {
            return num ++;
        }
    }

    public static void main(String[] args) {
        SyncTest syncTest = new SyncTest();

        // 開啟 10 個線程
        for (int i = 0; i < 10; i++) {
            new Thread(() -> 
                    System.out.println(Thread.currentThread().getName() 
                            + ":" + syncTest.numAutoIncrement())
            ).start();
        }
    }
}

3.2 使用原子類

jdk1.5 之后 java.util.concurrent.atomic 包下引入了諸如 AtomicInteger、AtomicLong 等特殊的原子性變量類。

這些變量類底層使用 CAS 算法與 volatile 關(guān)鍵字確保對所有的計數(shù)器操作都能保證原子性與可見性,也就解決了多線程安全問題。

使用方式如下

public class SyncTest {
    private AtomicInteger atomicInteger = new AtomicInteger(1);
    
    public int numAutoIncrement() {
        return atomicInteger.getAndIncrement();
    }

    public static void main(String[] args) {
        SyncTest syncTest = new SyncTest();

        for (int i = 0; i < 10; i++) {
            new Thread(() -> 
                    System.out.println(Thread.currentThread().getName() 
                            + ":" + syncTest.numAutoIncrement())
            ).start();
        }
    }
}

3.3 使用顯示 Lock 鎖

jdk1.5 之前,解決多線程共享對象訪問的機(jī)制只有 synchronizedvolatile。jdk1.5 新增了一種新的機(jī)制:ReentrantLock。ReentrantLock 并不是為替代內(nèi)置鎖而生的,當(dāng)內(nèi)置鎖機(jī)制不適用時,可以考慮使用這種更靈活的加鎖機(jī)制。

使用方式如下

public class SyncTest {
    private Lock lock = new ReentrantLock();
    private Integer num = 1;
    
    public int numAutoIncrement() {
        lock.lock();
        try {
            return num++;
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        SyncTest syncTest = new SyncTest();

        for (int i = 0; i < 10; i++) {
            new Thread(() -> 
                    System.out.println(Thread.currentThread().getName() 
                            + ":" + syncTest.numAutoIncrement())
            ).start();
        }
    }
}

從上面的代碼可以看出來,使用顯示鎖機(jī)制相對內(nèi)置鎖要麻煩一些,使用時要注意必須在 finally 語句塊中釋放鎖,否則當(dāng)出現(xiàn)異常時,獲取到的鎖永遠(yuǎn)不會被釋放,在代碼中存在這種情況無疑是一種定時炸彈。

顯示鎖相較于內(nèi)置鎖還提供了等待可中斷、公平與非公平等功能,當(dāng)然還有一個優(yōu)點是顯示鎖更加靈活。

PS:
這篇博文中很多知識點拿出來都可以多帶帶寫一篇文章,這里只是總結(jié)了一部分重要的知識點,先讓大家對多線程有一個感性的認(rèn)識。后面會陸續(xù)的補(bǔ)充并發(fā)編程系列的文章。如果大家覺得寫得還行的話,請持續(xù)關(guān)注后面的文章。

參考資料

《Java 并發(fā)編程實戰(zhàn)》
《深入理解 Java 虛擬機(jī)》

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

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

相關(guān)文章

  • jvm原理

    摘要:在之前,它是一個備受爭議的關(guān)鍵字,因為在程序中使用它往往收集器理解和原理分析簡稱,是后提供的面向大內(nèi)存區(qū)數(shù)到數(shù)多核系統(tǒng)的收集器,能夠?qū)崿F(xiàn)軟停頓目標(biāo)收集并且具有高吞吐量具有更可預(yù)測的停頓時間。 35 個 Java 代碼性能優(yōu)化總結(jié) 優(yōu)化代碼可以減小代碼的體積,提高代碼運(yùn)行的效率。 從 JVM 內(nèi)存模型談線程安全 小白哥帶你打通任督二脈 Java使用讀寫鎖替代同步鎖 應(yīng)用情景 前一陣有個做...

    lufficc 評論0 收藏0
  • 線程編程完全指南

    摘要:在這個范圍廣大的并發(fā)技術(shù)領(lǐng)域當(dāng)中多線程編程可以說是基礎(chǔ)和核心,大多數(shù)抽象并發(fā)問題的構(gòu)思與解決都是基于多線程模型來進(jìn)行的。一般來說,多線程程序會面臨三類問題正確性問題效率問題死鎖問題。 多線程編程或者說范圍更大的并發(fā)編程是一種非常復(fù)雜且容易出錯的編程方式,但是我們?yōu)槭裁催€要冒著風(fēng)險艱辛地學(xué)習(xí)各種多線程編程技術(shù)、解決各種并發(fā)問題呢? 因為并發(fā)是整個分布式集群的基礎(chǔ),通過分布式集群不僅可以大...

    mengera88 評論0 收藏0
  • 【進(jìn)階1-4期】JavaScript深入帶你走進(jìn)內(nèi)存機(jī)制

    摘要:引擎對堆內(nèi)存中的對象進(jìn)行分代管理新生代存活周期較短的對象,如臨時變量字符串等。內(nèi)存泄漏對于持續(xù)運(yùn)行的服務(wù)進(jìn)程,必須及時釋放不再用到的內(nèi)存。 (關(guān)注福利,關(guān)注本公眾號回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實戰(zhàn)、面試指導(dǎo)) 本周正式開始前端進(jìn)階的第一期,本周的主題是調(diào)用堆棧,今天是第4天。 本計劃一共28期,每期重點攻克一個面試重難點,如果你還不了解本進(jìn)階計劃...

    不知名網(wǎng)友 評論0 收藏0
  • 帶你了解集合世界的fail-fast機(jī)制 和 CopyOnWriteArrayList 源碼詳解

    摘要:體現(xiàn)的就是適配器模式。數(shù)組對象集合世界中的機(jī)制機(jī)制集合世界中比較常見的錯誤檢測機(jī)制,防止在對集合進(jìn)行遍歷過程當(dāng)中,出現(xiàn)意料之外的修改,會通過異常暴力的反應(yīng)出來。而在增強(qiáng)循環(huán)中,集合遍歷是通過進(jìn)行的。 前言 學(xué)習(xí)情況記錄 時間:week 2 SMART子目標(biāo) :Java 容器 記錄在學(xué)習(xí)Java容器 知識點中,關(guān)于List的重點知識點。 知識點概覽: 容器中的設(shè)計模式 從Array...

    young.li 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<