日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

Java 7 并发编程指南

發(fā)布時間:2025/4/16 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 7 并发编程指南 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文是發(fā)表在并發(fā)編程網(wǎng)上翻譯后的 《Java 7 并發(fā)編程指南》,這里對其中的目錄做個更加詳細的描述,并且寫出了重點說明,方便日后快速查閱。建議仔細查看每節(jié)的代碼實現(xiàn),非常具有參考價值。可以直接點擊標(biāo)題,查看原文。

原文目錄地址:http://ifeve.com/java-7-concurrency-cookbook/
代碼實現(xiàn):https://github.com/Wang-Jun-Chao/java-concurrency

目錄

前言

第一章: 線程管理

  • 介紹

    本節(jié)主要介紹線程基本的操作。

  • 線程的創(chuàng)建和運行

    在Java中,我們有2個方式創(chuàng)建線程:

    • 通過直接繼承thread類,然后覆蓋run()方法。
    • 構(gòu)建一個實現(xiàn)Runnable接口的類, 然后創(chuàng)建一個thread類對象并傳遞Runnable對象作為構(gòu)造參數(shù)

    之后調(diào)用這個線程對象的start()對象即可運行。

  • 獲取和設(shè)置線程信息

    Thread類的對象中保存了一些屬性信息能夠幫助我們來辨別每一個線程,知道它的狀態(tài),調(diào)整控制其優(yōu)先級。 這些屬性是:

    • ID: 每個線程的獨特標(biāo)識。
    • Name: 線程的名稱。
    • Priority: 線程對象的優(yōu)先級。優(yōu)先級別在1-10之間,1是最低級,10是最高級。不建議改變它們的優(yōu)先級,但是你想的話也是可以的。
    • Status: 線程的狀態(tài)。在Java中,線程只能有這6種中的一種狀態(tài): new, runnable, blocked, waiting, time waiting, 或 terminated.
  • 線程的中斷

    Java提供中斷機制來通知線程表明我們想要結(jié)束它。中斷機制的特性是線程需要檢查是否被中斷,而且還可以決定是否響應(yīng)結(jié)束的請求。所以,線程可以忽略中斷請求并且繼續(xù)運行。如果需要中斷線程,只需要調(diào)用線程對象的interrupt()方法即可,線程通過isInterrupted()方法來檢測自己是否被中斷。比如,你可以像例子中一樣,輪詢檢測自己是否被中斷,如果被中斷了就直接return。

  • 操作線程的中斷機制

    我們可以選擇使用拋出InterruptedException異常的方式來停止線程。通常它可以由并發(fā)API來拋出比如sleep()方法

  • 線程的睡眠和恢復(fù)

    當(dāng)你調(diào)用sleep()方法, Thread 離開CPU并在一段時間內(nèi)停止運行。在這段時間內(nèi),它是不消耗CPU時間的,使得CPU可以執(zhí)行其他任務(wù)。

    當(dāng) Thread 是睡眠并且處于中斷狀態(tài)(比如調(diào)用了線程的interrupt()方法)的時候,sleep方法會立刻拋出InterruptedException異常并不會一直等到睡眠時間過去。

    Java 并發(fā) API 有另一種方法能讓線程對象離開 CPU。它是 yield() 方法, 它向JVM表示線程對象可以讓CPU執(zhí)行其他任務(wù)。JVM 不保證它會遵守請求。通常,它只是用來試調(diào)的。

  • 等待線程的終結(jié)

    當(dāng)線程調(diào)用某個其他線程的join()方法時,它會暫停當(dāng)前線程,直到被調(diào)用join()方法的其他線程執(zhí)行完成。

  • 守護線程的創(chuàng)建和運行

    調(diào)用線程對象的setDaemon(true);來使其成為一個守護線程。

  • 處理線程的不受控制異常

    Java里有2種異常:

    • 檢查異常(Checked exceptions): 這些異常必須強制捕獲它們或在一個方法里的throws子句中。 例如, IOException 或者ClassNotFoundException。
    • 未檢查異常(Unchecked exceptions): 這些異常不用強制捕獲它們。例如, NumberFormatException。當(dāng)一個非檢查異常被拋出,默認的行為是在控制臺寫下stack trace并退出程序。

    我們可以使用線程對象的setUncaughtExceptionHandler方法來設(shè)置未檢測異常的回調(diào)函數(shù)。這個回調(diào)函數(shù)以Thread 對象和 Exception 作為參數(shù)。

    此外調(diào)用Thread.setDefaultUncaughtExceptionHandler()可以為應(yīng)用里的所有線程對象建立異常 handler 。

    當(dāng)一個未捕捉的異常在線程里被拋出,JVM會尋找此異常的3種可能潛在的處理者(handler)。首先, 它尋找這個未捕捉的線程對象的異常handle,如我們在在這個指南中學(xué)習(xí)的。如果這個handle 不存在,那么JVM會在線程對象的ThreadGroup里尋找非捕捉異常的handler,如在處理線程組內(nèi)的不受控制異常里介紹的那樣(下面的第12節(jié))。如果此方法也不存在,那么 JVM 會尋找默認非捕捉異常handle,就是調(diào)用Thread.setDefaultUncaughtExceptionHandler()設(shè)置的那個handle。如果沒有一個handler存在, 那么 JVM會把異常的 stack trace 寫入操控臺并結(jié)束任務(wù)。

  • 使用本地線程變量

    使用ThreadLocal來存儲線程局部變量。它的使用類似于這種:

  • /*** 線程局部變量,其中的內(nèi)容不能共享,線程被初始化時會創(chuàng)建其包含的變量*/ private static ThreadLocal<Date> startDate = new ThreadLocal<Date>() {@Overrideprotected Date initialValue() {return new Date();} };
  • 線程組

    Java 提供 ThreadGroup 類來組織線程。 ThreadGroup 對象可以由 Thread 對象組成和由另外的 ThreadGroup 對象組成,生成線程樹結(jié)構(gòu)。

    ThreadGroup 類儲存線程對象和其他有關(guān)聯(lián)的 ThreadGroup 對象,所以它可以訪問他們的所有信息 (例如,狀態(tài)) 和全部成員的操作表現(xiàn) (例如,中斷)。

  • 處理線程組內(nèi)的不受控制異常

    重寫ThreadGroup的uncaughtException方法來為線程組設(shè)置未捕獲異常的回調(diào)方法

  • 用線程工廠創(chuàng)建線程

    實現(xiàn)ThreadFactory接口來使用線程工廠創(chuàng)建線程,你需要知道使用線程工廠創(chuàng)建線程有什么優(yōu)勢,一般來說它具有下面這些優(yōu)勢:

    • 更簡單的改變了類的對象創(chuàng)建或者說創(chuàng)建這些對象的方式。
    • 更簡單的為了限制的資源限制了對象的創(chuàng)建。 例如, 我們只new一個此類型的對象。
    • 更簡單的生成創(chuàng)建對象的統(tǒng)計數(shù)據(jù)。
  • 第二章 : 基本線程同步

  • 介紹

    在并發(fā)應(yīng)用程序中,多個線程讀或?qū)懴嗤臄?shù)據(jù)或訪問同一文件或數(shù)據(jù)庫連接這是正常的。這些共享資源會引發(fā)錯誤或數(shù)據(jù)不一致的情況,我們必須通過一些機制來避免這些錯誤。

  • 同步方法

    synchronized關(guān)鍵字基本使用

  • 在同步的類里安排獨立屬性

    當(dāng)你使用synchronized關(guān)鍵字來保護代碼塊時,你必須通過一個對象的引用作為參數(shù)。通常,你將會使用this關(guān)鍵字來引用執(zhí)行該方法的對象,但是你也可以使用其他對象引用。通常情況下,這些對象被創(chuàng)建只有這個目的。比如,你在一個類中有被多個線程共享的兩個獨立屬性。你必須同步訪問每個變量,如果有一個線程訪問一個屬性和另一個線程在同一時刻訪問另一個屬性,這是沒有問題的。

  • 在同步代碼中使用條件

    涉及wait(),notify(),和notifyAll() 方法。

    一個線程可以在synchronized代碼塊中調(diào)用wait()方法。如果在synchronized代碼塊外部調(diào)用wait()方法,JVM會拋出IllegalMonitorStateException異常。當(dāng)線程調(diào)用wait()方法,JVM讓這個線程睡眠,并且釋放控制 synchronized代碼塊的對象,這樣,雖然它正在執(zhí)行但允許其他線程執(zhí)行由該對象保護的其他synchronized代碼塊。為了喚醒線程,你必 須在由相同對象保護的synchronized代碼塊中調(diào)用notify()或notifyAll()方法。

    通常我們會將wait()寫在一個while()循環(huán)中,以在喚醒之后再次檢測是否滿足條件,滿足則繼續(xù)執(zhí)行,否則再次進入wait(),因為wait()有的時候會被錯誤的喚醒。。

  • 使用Lock來同步代碼塊

    Java提供另外的機制用來同步代碼塊。它比synchronized關(guān)鍵字更加強大、靈活。它是基于Lock接口和實現(xiàn)它的類(如ReentrantLock)。這種機制有如下優(yōu)勢:

    • 它允許以一種更靈活的方式來構(gòu)建synchronized塊。使用synchronized關(guān)鍵字,你必須以結(jié)構(gòu)化方式得到釋放synchronized代碼塊的控制權(quán)。Lock接口允許你獲得更復(fù)雜的結(jié)構(gòu)來實現(xiàn)你的臨界區(qū)。
    • Lock 接口比synchronized關(guān)鍵字提供更多額外的功能。新功能之一是實現(xiàn)的tryLock()方法。這種方法試圖獲取鎖的控制權(quán)并且如果它不能獲取該鎖是因為其他線程在使用這個鎖,它將返回這個鎖。使用synchronized關(guān)鍵字的時候,當(dāng)線程A試圖執(zhí)行synchronized代碼塊,如果線程B正在執(zhí)行它,那么線程A將阻塞直到線程B執(zhí)行完synchronized代碼塊。而使用鎖,你可以執(zhí)行tryLock()方法,這個方法返回一個 Boolean值表示是否有其他線程正在運行這個鎖所保護的代碼。
    • 當(dāng)有多個讀者和一個寫者時,Lock接口允許讀寫操作分離。
    • Lock接口比synchronized關(guān)鍵字提供更好的性能。
  • 使用讀/寫鎖來同步數(shù)據(jù)訪問

    鎖所提供的最重要的改進之一就是ReadWriteLock接口和唯一 一個實現(xiàn)它的ReentrantReadWriteLock類。這個類提供兩把鎖,一把用于讀操作和一把用于寫操作。同時可以有多個線程執(zhí)行讀操作。當(dāng)一個線程正在執(zhí)行一個寫操作,不可能有任何線程執(zhí)行讀操作。當(dāng)一個線程正在執(zhí)行一個讀操作,也不可能有任何線程執(zhí)行寫操作。總結(jié)來說就是:讀讀不互斥,讀寫,寫寫都是互斥的。

  • 修改Lock的公平性

    ReentrantLock類和 ReentrantReadWriteLock類的構(gòu)造器中,允許一個名為fair的boolean類型參數(shù),它允許你來控制這些類的行為。默認值為 false,這將啟用非公平模式。在這個模式中,當(dāng)有多個線程正在等待一把鎖(ReentrantLock或者 ReentrantReadWriteLock),這個鎖必須選擇它們中間的一個來獲得進入臨界區(qū),選擇任意一個是沒有任何標(biāo)準(zhǔn)的。true值將開啟公平 模式。在這個模式中,當(dāng)有多個線程正在等待一把鎖(ReentrantLock或者ReentrantReadWriteLock),這個鎖必須選擇它們 中間的一個來獲得進入臨界區(qū),它將選擇等待時間最長的線程。

  • 在Lock中使用多條件

    涉及await()、signal()和signallAll();

    這有點像前面的第4節(jié)在同步代碼中使用條件。但是await()、signal()和signallAll()是配合Lock來進行使用的。而wait(),notify(),和notifyAll() 是配合synchronized來使用的。并且前者可以實現(xiàn)鎖上的多個條件的等待??梢圆榭丛撜鹿?jié)示例代碼中的Buffer類來查看如何使用。

  • 第三章: 線程同步工具

  • 介紹

    在第二章,基本的線程同步中,我們學(xué)會了以下2個同步機制:

    • 關(guān)鍵詞同步(synchronized)
    • Lock接口和它的實現(xiàn)類們:ReentrantLock, ReentrantReadWriteLock.ReadLock, 和 ReentrantReadWriteLock.WriteLock

    在此章節(jié),我們將學(xué)習(xí)怎樣使用高等級的機制來達到多線程的同步。這些高等級機制有:

    • Semaphores: 控制訪問多個共享資源的計數(shù)器。此機制是并發(fā)編程的最基本的工具之一,而且大部分編程語言都會提供此機制。
    • CountDownLatch: CountDownLatch 類是Java語言提供的一個機制,它允許線程等待多個操作的完結(jié)。
    • CyclicBarrier: CyclicBarrier 類是又一個java語言提供的機制,它允許多個線程在同一個點同步。
    • Phaser: Phaser類是又一個java語言提供的機制,它控制并發(fā)任務(wù)分成段落來執(zhí)行。全部的線程在繼續(xù)執(zhí)行下一個段之前必須等到之前的段執(zhí)行結(jié)束。這是Java 7 API的一個新特性。
    • Exchanger: Exchanger類也是java語言提供的又一個機制,它提供2個線程間的數(shù)據(jù)交換點。
  • 控制并發(fā)訪問一個資源

    使用Semaphore(信號量)類來實現(xiàn)一種比較特殊的semaphores種類,稱為binary semaphores。

  • 控制并發(fā)訪問多個資源

    使用semaphores來保護多個資源的副本,也就是說當(dāng)你有一個代碼片段可以同時被多個線程執(zhí)行。關(guān)于這一點可以查看該章節(jié)的示例代碼,它很好的說明了一個使用它的場景。信號量也可以用來控制并發(fā)線程數(shù)量。

  • 等待多個并發(fā)事件完成

    CountDownLatch 類的基本使用方法。有一個線程調(diào)用CountDownLatch對象的await()方法等待,等待其他線程完成必須在await()方法之后的之前完成的任務(wù)。

  • 在一個相同點同步任務(wù)

    CyclicBarrier 類有一個內(nèi)部計數(shù)器控制到達同步點的線程數(shù)量。每次線程到達同步點,它調(diào)用 await() 方法告知 CyclicBarrier 對象到達同步點了。CyclicBarrier 把線程放入睡眠狀態(tài)直到全部的線程都到達他們的同步點。

    當(dāng)全部的線程都到達他們的同步點,CyclicBarrier 對象叫醒全部正在 await() 方法中等待的線程們,然后,選擇性的,為CyclicBarrier的構(gòu)造函數(shù) 傳遞的 Runnable 對象(例子里,是 Grouper 對象)創(chuàng)建新的線程執(zhí)行外加任務(wù)。

  • 運行并發(fā)階段性任務(wù)

    Phaser類的使用,可以參考這里來加深對Phaser的使用。

  • 控制并發(fā)階段性任務(wù)的改變

    同上節(jié),在參考的文章中有說明。

  • 在并發(fā)任務(wù)間交換數(shù)據(jù)

    Exchange類的使用,2個線程間定義同步點,當(dāng)2個線程到達這個點,他們相互交換數(shù)據(jù)類型,使用第一個線程的數(shù)據(jù)類型變成第二個的,然后第二個線程的數(shù)據(jù)類型變成第一個的。

  • 第四章: 線程執(zhí)行者

  • 介紹
    提出Executor framework概念,這有點像我們之前提到的線程工廠,實際上這些線程執(zhí)行者框架就是使用線程工廠來創(chuàng)建線程的。這里給出Executor框架類圖
  • 創(chuàng)建一個線程執(zhí)行者
    ThreadPoolExecutor的基本使用,execute提交任務(wù),shutdown停止線程執(zhí)行者。
  • 創(chuàng)建一個大小固定的線程執(zhí)行者
    上一節(jié)我們使用newCachedThreadPool()來創(chuàng)建ThreadPoolExecutor對象,它的線程池為無限大。但是在這里我們需要使用newFixedThreadPool來創(chuàng)建線程池大小固定的ThreadPoolExecutor對象,定長線程池的大小最好根據(jù)系統(tǒng)資源進行設(shè)置。如Runtime.getRuntime().availableProcessors()。
  • 執(zhí)行者執(zhí)行返回結(jié)果的任務(wù)
    Executor framework還可以并發(fā)執(zhí)行返回結(jié)果的任務(wù),這個時候我們使用的是submit函數(shù)提交任務(wù),而不是execute。submit()函數(shù)將會返回一個Future對象,使用這個對象的get方法,你將會獲得執(zhí)行結(jié)果,不止如此Future還提供了其他獲得任務(wù)執(zhí)行信息和控制任務(wù)的方法,它使你不至于將任務(wù)交給執(zhí)行器之后對任務(wù)狀態(tài)一無所知。
  • 運行多個任務(wù)并處理第一個結(jié)果
    如果你不需要像前面一樣,需要所有提交的任務(wù)的結(jié)果,而是只需要最先完成的任務(wù)的結(jié)果,你可以使用執(zhí)行器的invokeAny()方法。該方法接收一個任務(wù)列表作為參數(shù),返回最先執(zhí)行完成的任務(wù)的結(jié)果。
  • 運行多個任務(wù)并處理所有的結(jié)果
    如果你覺得像第4小節(jié)講到的那樣一個一個submit()任務(wù),然后獲得Future比較繁雜,你可以直接將任務(wù)列表使用invokeAll()方法直接全部給執(zhí)行器,它會返回一個對應(yīng)的Future列表,對應(yīng)的Future在列表中的位置和提交的任務(wù)一致,invokeAll將所有的任務(wù)提交后,等待全部任務(wù)完成才返回;
  • 在延遲后執(zhí)行者運行任務(wù)
    創(chuàng)建ScheduledThreadPoolExecutor和利用這個執(zhí)行器安排任務(wù)在指定的時間后執(zhí)行。它是使用這個執(zhí)行器對象的schedule()函數(shù)來完成這個操作的,如:executor.schedule(task, delayTime, TimeUnit.SECONDS);
  • 執(zhí)行者定期的執(zhí)行任務(wù)
    使用ScheduledThreadPoolExecutor類還可以執(zhí)行定期任務(wù),這一點是調(diào)用執(zhí)行器對象的scheduleAtFixedRate()方法來實現(xiàn)的。當(dāng)執(zhí)行器對象調(diào)用shutdown()方法后,將不會執(zhí)行周期性任務(wù)。
  • 執(zhí)行者取消任務(wù)
    通過調(diào)用執(zhí)行器返回的Future的cancel方法,可以取消任務(wù)的執(zhí)行。
  • 執(zhí)行者控制一個結(jié)束任務(wù)
    重寫FutureTask類的done()方法來實現(xiàn)在執(zhí)行者執(zhí)行任務(wù)完成后執(zhí)行額外的一些代碼。
  • 執(zhí)行者分離運行任務(wù)和處理結(jié)果
    使用CompletionService類來實現(xiàn)一邊執(zhí)行任務(wù)線程,一邊處理執(zhí)行完任務(wù)線程的結(jié)果。原文在這里的解釋不是特別清除,可以參考這里
  • 執(zhí)行者控制被拒絕的任務(wù)
    實現(xiàn)RejectedExecutionHandler,來處理線程池shutdown()后提交的任務(wù)。
  • 第五章: Fork/Join 框架

  • 介紹

    Fork/Join框架被設(shè)計用來解決可以使用分而治之技術(shù)將任務(wù)分解成更小的問題。具體可以查看該節(jié)內(nèi)容。

  • 創(chuàng)建 Fork/Join 池

    創(chuàng)建一個ForkJoinPool對象來執(zhí)行任務(wù)。創(chuàng)建一個ForkJoinPool執(zhí)行的ForkJoinTask類。

  • 加入任務(wù)的結(jié)果

    在上一節(jié)的基礎(chǔ)上,添加說明如果處理任務(wù)的子線程有返回結(jié)果如何處理。主要就是在Override的compute()函數(shù)中返回結(jié)果,然后可以使用處理任務(wù)的子線程的get方法獲得這個返回結(jié)果。并且從例子中可以看出,Fork/Join框架可以提交不一樣的子任務(wù),具體表現(xiàn)如下;

    所以Fork/Join框架更加強調(diào)的是,父線程等待invokeAll出來的子線程完成后,從invokeAll退出繼續(xù)完成接下來的邏輯程序。父線程從邏輯上來說像是從invokeAll處暫停了(等待子線程完成后退出),但是實際上父線程的線程資源還可以去執(zhí)行其他沒有被執(zhí)行的任務(wù),但是執(zhí)行的內(nèi)容不是父線程原來的內(nèi)容,這樣可以減少創(chuàng)建的線程的數(shù)量,這使用了work-stealing算法,即分配一個新的任務(wù)給正在執(zhí)行睡眠任務(wù)的工作線程。

  • 異步運行任務(wù)

    使用ForkJoinTask的異步方法(比如fork()),來向線程池提交任務(wù)。之前我們使用的是同步方法(比如invokeAll()),這將阻塞父線程。而異步方法將繼續(xù)父線程的內(nèi)容,我們使用異步方法也就意味著不能使用work-stealing算法,除非在父線程中使用調(diào)用join()或get()方法來等待任務(wù)的完成時。

  • 任務(wù)中拋出異常

    處理任務(wù)中拋出的異常,檢查異常不能從compute()中拋出,你必須手動解決(使用try-catch)。未檢查異常將不會輸入任何信息到控制臺。就像沒有發(fā)生一樣,但是拋出非檢查異常的線程和它的所有父輩異常不會正常執(zhí)行。我們自然不會希望,任務(wù)沒有正常執(zhí)行但是又沒有給任何提示,所以最后我們可以使用task.isCompletedAbnormally()來檢查execute()給線程池的任務(wù)到底有沒有拋出非檢查異常。
    非檢查異常也可以使用try-catch來捕獲,但是一般我們是不會這樣做的,因為非檢查異常的拋出一般是意味著我們的代碼有錯誤,應(yīng)該去改正它。

  • 取消任務(wù)

    ForkJoinTask類提供cancel()方法用于這個目的。當(dāng)你想要取消一個任務(wù)時,有一些點你必須考慮一下,這些點如下:

    • ForkJoinPool類并沒有提供任何方法來取消正在池中運行或等待的所有任務(wù)。
    • 當(dāng)你取消一個任務(wù)時,你不能取消一個已經(jīng)執(zhí)行的任務(wù)。

    但是你依舊可以調(diào)用運行的任務(wù)的cancel()方法,但是具體執(zhí)不執(zhí)行就要看到底這個任務(wù)有沒有在運行了??梢詤⒖际纠a中,創(chuàng)建一個TaskManager類來管理任務(wù)。

  • 第六章: 并發(fā)集合

  • 介紹
    這里需要了解到并發(fā)集合分為兩種:
    • 阻塞集合:這種集合包括添加和刪除數(shù)據(jù)的操作。如果操作不能立即進行,是因為集合已滿或者為空,該程序?qū)⒈蛔枞?#xff0c;直到操作可以進行。
    • 非阻塞集合:這種集合也包括添加和刪除數(shù)據(jù)的操作。如果操作不能立即進行,這個操作將返回null值或拋出異常,但該線程將不會阻塞。
  • 使用非阻塞線程安全列表
    非阻塞并發(fā)列表ConcurrentLinkedDeque類。
  • 使用阻塞線程安全列表
    阻塞列表LinkedBlockingDeque類。
  • 用優(yōu)先級對使用阻塞線程安全列表排序
    阻塞優(yōu)先隊列PriorityBlockingQueue類
  • 使用線程安全與帶有延遲元素的列表
    阻塞隊列DelayedQueue類,可以控制元素延遲出現(xiàn)
  • 使用線程安全的可遍歷映射
    ConcurrentSkipListMap提供了多線程并發(fā)存取<Key, Value>數(shù)據(jù)并且希望保證數(shù)據(jù)有序時的數(shù)據(jù)結(jié)構(gòu),底層使用跳表實現(xiàn)。關(guān)于ConcurrentSkipListMap更加詳細的信息可以參考這里
  • 生成并行隨機數(shù)
    使用ThreadLocalRandom類來生成隨機數(shù)
  • 使用原子變量
    使用原子變量,原子變量不使用任何鎖或者其他同步機制來保護它們的值的訪問。他們的全部操作都是基于CAS操作。關(guān)于CAS操作更具體的內(nèi)容網(wǎng)上有很多,務(wù)必理解。特別是要理解底層是如何實現(xiàn)的。我建議查看這里。特別是其一直深入到底層的分析,非常有意思。
  • 使用原子陣列
    使用原子數(shù)組,這和原子變量差不多。
  • 第七章: 定制并發(fā)類

  • 介紹
  • 定制ThreadPoolExecutor 類

    復(fù)寫ThreadPoolExecutor 類的一些方法。這里需要去理解ThreadPoolExecutor類構(gòu)造函數(shù)的一些參數(shù)。

  • 實現(xiàn)一個優(yōu)先級制的執(zhí)行者類

    實現(xiàn)一個按優(yōu)先級執(zhí)行的ThreadPoolExecutor 類,實際上就是TASK(任務(wù))實現(xiàn)Comparable接口,而后將PriorityBlockingQueue作為ThreadPoolExecutor的提交任務(wù)時所使用的隊列。

  • 實現(xiàn)ThreadFactory接口來生成自定義線程

    使用線程工廠來創(chuàng)造線程

  • 在執(zhí)行者對象中使用我們的 ThreadFactory

    以自己的線程工廠為參數(shù)構(gòu)造執(zhí)行器對象,使執(zhí)行器對象使用我們的線程工廠創(chuàng)造線程。

  • 在計劃好的線程池中定制運行任務(wù)

    使用ScheduledThreadPoolExecutor 來運行計劃任務(wù)。

  • 實現(xiàn)ThreadFactory接口來生成自定義線程給Fork/Join框架

    實現(xiàn)ThreadFactory接口創(chuàng)建自己的線程工廠提供給Fork/Join框架使用,而不是使用其默認的線程工廠。需要明確的是,不要將任務(wù)(callable或runnable)和線程(thread)混為一談。一個線程可以在不同的時期執(zhí)行多個任務(wù)。線程也可以有自己的內(nèi)存空間,保存自己的數(shù)據(jù)。如果能將任務(wù)和線程這兩個概念區(qū)分開來,代碼還是比較好理解的。

  • 在Fork/Join框架中定制運行任務(wù)

    上一節(jié),我們?yōu)镕ork/Join框架創(chuàng)建的線程工廠,這一節(jié)我們將定制我們自己的任務(wù)類,加入到Fork/Join框架的任務(wù)類一般都繼承ForkJoinTask這個抽象類,一般我們使用:

    • RecursiveAction: 如果你的任務(wù)沒有返回結(jié)果
    • RecursiveTask: 如果你的任務(wù)返回結(jié)果

    但是,這里我們將自己實現(xiàn)一個類繼承ForkJoinTask這個抽象類,從而使任務(wù)運行更加更加符合我們的想法。
    當(dāng)我們想去實現(xiàn)和任務(wù)具體的內(nèi)容沒有關(guān)系的功能的時候,比如統(tǒng)計,控制線程的時候,我們可以嘗試定制自己的并發(fā)類。

  • 實現(xiàn)一個自定義鎖類

    實現(xiàn)Lock接口,從而實現(xiàn)自定義鎖類。

  • 實現(xiàn)一個基于優(yōu)先級傳輸Queue

    本節(jié)實現(xiàn)一個有優(yōu)先級的傳輸隊列,用來解決生產(chǎn)者/消費者問題。

  • 實現(xiàn)你自己的原子對象

    繼承原子變量,實現(xiàn)自己的類似原子變量的一些操作,比如并發(fā)安全的加1或者減1。

  • 第八章: 測試并發(fā)應(yīng)用程序

  • 介紹

    本節(jié)主要講述如何測試你的并發(fā)應(yīng)用程序是否正確。2-5節(jié)都是說明如何從并發(fā)類中獲取相應(yīng)的信息,也就是通過獲取狀態(tài)變量來對其相關(guān)對象進行監(jiān)控。下面每節(jié)的內(nèi)容很直白的體現(xiàn)在小節(jié)題目中了。

  • 監(jiān)控鎖接口
  • 監(jiān)控Phaser類
  • 監(jiān)控執(zhí)行者框架
  • 監(jiān)控Fork/Join池
  • 編寫有效的日志
  • FindBugs分析并發(fā)代碼
  • 配置Eclipse來調(diào)試并發(fā)代碼
  • 配置NetBeans來調(diào)試并發(fā)代碼
  • MultithreadedTC測試并發(fā)代碼
  • 《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

    總結(jié)

    以上是生活随笔為你收集整理的Java 7 并发编程指南的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。