成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java線程池簡單總結(jié)

CoorChice / 910人閱讀

摘要:本文主要內(nèi)容為簡單總結(jié)中線程池的相關(guān)信息。方法簇方法簇用于創(chuàng)建固定線程數(shù)的線程池。三種常見線程池的對比上文總結(jié)了工具類創(chuàng)建常見線程池的方法,現(xiàn)對三種線程池區(qū)別進(jìn)行比較。

概述

線程可認(rèn)為是操作系統(tǒng)可調(diào)度的最小的程序執(zhí)行序列,一般作為進(jìn)程的組成部分,同一進(jìn)程中多個線程可共享該進(jìn)程的資源(如內(nèi)存等)。在單核處理器架構(gòu)下,操作系統(tǒng)一般使用分時的方式實(shí)現(xiàn)多線程;在多核處理器架構(gòu)下,多個線程能夠做到真正的在不同處理核心并行處理。
無論使用何種方式實(shí)現(xiàn)多線程,正確使用多線程都可以提高程序性能,或是吞吐量,或是響應(yīng)時間,甚至兩者兼具。如何正確使用多線程涉及較多的理論及最佳實(shí)踐,本文無法詳細(xì)展開,可參考如《Programming Concurrency on the JVM》等書籍。
本文主要內(nèi)容為簡單總結(jié)Java中線程池的相關(guān)信息。

Java線程使用及特點(diǎn)

Java中提供Thread作為線程實(shí)現(xiàn),一般有兩種方式:

直接集成Thread類:

class PrimeThread extends Thread {
    long minPrime;
    PrimeThread(long minPrime) {
        this.minPrime = minPrime;
    }

    public void run() {
        // compute primes larger than minPrime
        . . .
    }
}
class Starter{
    public static void main(){
        PrimeThread p = new PrimeThread(143);
        p.start();
    }
}

實(shí)現(xiàn)Runnable 接口:

class PrimeRun implements Runnable {
    long minPrime;
    PrimeRun(long minPrime) {
        this.minPrime = minPrime;
    }

    public void run() {
        // compute primes larger than minPrime
        . . .
    }
}
class Starter{
    public static void main(){
        PrimeRun p = new PrimeRun(143);
        new Thread(p).start();
    }
}

線程是屬于操作系統(tǒng)的概念,Java中的多線線程實(shí)現(xiàn)一定會依托于操作系統(tǒng)支持。HotSpot虛擬機(jī)中對多線程的實(shí)現(xiàn)實(shí)際上是使用了一對一的映射模型,即一個Java進(jìn)程映射到一個輕量級進(jìn)程(LWP)之中。在使用Threadstart方法后,HotSpot創(chuàng)建本地線程并與Java線程關(guān)聯(lián)。在此過程之中虛擬機(jī)需要創(chuàng)建多個對象(如OSThread等)用于跟蹤線程狀態(tài),后續(xù)需要進(jìn)行線程初始化工作(如初始換ThreadLocalAllocBuffer對象等),最后啟動線程調(diào)用上文實(shí)現(xiàn)的run方法。
由此可見創(chuàng)建線程的成本較高,如果線程中run函數(shù)中業(yè)務(wù)代碼執(zhí)行時間非常短且消耗資源較少的情況下,可能出現(xiàn)創(chuàng)建線程成本大于執(zhí)行真正業(yè)務(wù)代碼的成本,這樣難以達(dá)到提升程序性能的目的。
由于創(chuàng)建線程成本較大,很容易想到通過復(fù)用已創(chuàng)建的線程已達(dá)到減少線程創(chuàng)建成本的方法,此時線程池就可以發(fā)揮作用。

Java線程池

Java線程池主要核心類(接口)為Executor,ExecutorService,Executors等,具體關(guān)系如下圖所示:

Executor接口

由以上類圖可見在線程池類結(jié)構(gòu)體系中Executor作為最初始的接口,該接口僅僅規(guī)定了一個方法void execute(Runnable command),此接口作用為規(guī)定線程池需要實(shí)現(xiàn)的最基本方法為可運(yùn)行實(shí)現(xiàn)了Runnable接口的任務(wù),并且開發(fā)人員不需要關(guān)心具體的線程池實(shí)現(xiàn)(在實(shí)際使用過程中,仍需要根據(jù)不同任務(wù)特點(diǎn)選擇不同的線程池實(shí)現(xiàn)),將客戶端代碼與運(yùn)行客戶端代碼的線程池解耦。

ExecutorService接口

Executor接口雖然完成了業(yè)務(wù)代碼與線程池的解耦,但沒有提供任何與線程池交互的方法,并且僅僅支持沒有任何返回值的Runnable任務(wù)的提交,在實(shí)際業(yè)務(wù)實(shí)現(xiàn)中功能略顯不足。為了解決以上問題,JDK中增加了擴(kuò)展Executor接口的子接口ExecutorService
ExecutorService接口主要在兩方面擴(kuò)展了Executor接口:

提供針對線程池的多個管理方法,主要包括停止任務(wù)提交、停止線程池運(yùn)行、判斷線程池是否停止運(yùn)行及線程池中任務(wù)是否運(yùn)行完成;

增加submit的多個重載方法,該方法可在提交運(yùn)行任務(wù)時,返回給提交任務(wù)的線程一個Future對象,可通過該對象對提交的任務(wù)進(jìn)行控制,如取消任務(wù)或獲取任務(wù)結(jié)果等(Future對象如何實(shí)現(xiàn)此功能另行討論)。

Executors工具類

Executors是主要為了簡化線程池的創(chuàng)建而提供的工具類,通過調(diào)用各靜態(tài)工具方法返回響應(yīng)的線程池實(shí)現(xiàn)。通過對其方法的觀察可將其提供的工具方法歸為如下幾類:

創(chuàng)建ExecutorService對象的工具:又可細(xì)分為創(chuàng)建FixedThreadPool、SingleThreadPool、CachedThreadPool、WorkStealingPool、UnconfigurableExecutorServiceSingleThreadScheduledExecutorThreadScheduledExecutor;

創(chuàng)建ThreadFactory對象;

Runnable等對象封裝為Callable對象。

以上各工具方法中使用最廣泛的為newCachedThreadPoolnewFixedThreadPoolnewSingleThreadExecutor,這三個方法創(chuàng)建的ExecutorService對象均是其子類ThreadPoolExecutor(嚴(yán)格來說newSingleThreadExecutor方法返回的是FinalizableDelegatedExecutorService對象,其封裝了ThreadPoolExecutor,為何如此實(shí)現(xiàn)后文在做分析),下文著重分析ThreadPoolExecutor類。至于其他ExecutorService實(shí)現(xiàn)類,如ThreadScheduledExecutor本文不做詳細(xì)分析。

ThreadPoolExecutor

ThreadPoolExecutor類是線程池ExecutorService的重要實(shí)現(xiàn)類,在工具類Executors中構(gòu)建的線程池對象,有大部分均是ThreadPoolExecutor實(shí)現(xiàn)。
ThreadPoolExecutor類提供多個構(gòu)造參數(shù)對線程池進(jìn)行配置,代碼如下:

public ThreadPoolExecutor(int corePoolSize,
                        int maximumPoolSize,
                        long keepAliveTime,
                        TimeUnit unit,
                        BlockingQueue workQueue,
                        ThreadFactory threadFactory,
                        RejectedExecutionHandler handler)

現(xiàn)在對各個參數(shù)作用進(jìn)行總結(jié):

參數(shù)名稱 參數(shù)類型 參數(shù)用途
corePoolSize int 核心線程數(shù),線程池中會一直保持該數(shù)量的線程,即使這些線程是空閑的狀態(tài),如果設(shè)置allowCoreThreadTimeOut屬性(默認(rèn)為false)為true,則空閑超過超時時間的核心線程可以被回收
maximumPoolSize int 最大線程數(shù),當(dāng)前線程池中可存在的最大線程數(shù)
keepAliveTime long 線程存活時間,當(dāng)當(dāng)前線程池中線程數(shù)大于核心線程數(shù)時,空閑線程等待新任務(wù)的時間,超過該時間則停止空閑線程
unit TimeUnit 時間單位,keepAliveTime屬性的時間單位
workQueue BlockingQueue 等待隊列,存儲待執(zhí)行的任務(wù)
threadFactory ThreadFactory 線程工廠,線程池創(chuàng)建線程時s使用
handler RejectedExecutionHandler 拒絕執(zhí)行處理器,當(dāng)提交任務(wù)被拒絕(當(dāng)?shù)却犃袧M,且線程達(dá)到最大限制后)時調(diào)用

在使用該線程池時有一個重要的參數(shù)起效順序:

提交任務(wù)時,當(dāng)當(dāng)前運(yùn)行的線程數(shù)小于核心線程時,則啟動新的線程執(zhí)行任務(wù);

提交任務(wù)時,當(dāng)前運(yùn)行線程數(shù)大于等于核心線程數(shù),將當(dāng)前任務(wù)加入等待隊列中;

將任務(wù)添加到等待隊列失敗時(如隊列滿),嘗試新建線程運(yùn)行任務(wù);

新建線程時,線程池關(guān)閉或達(dá)到最大線程數(shù),則拒絕任務(wù),調(diào)用handler進(jìn)行處理。

ThreadFactory有默認(rèn)的實(shí)現(xiàn)為Executors.DefaultThreadFactory,其創(chuàng)建線程主要額外工作為將新建的線程加入當(dāng)前線程組,并且將線程的名稱置為pool-x-thread-y的形式。

ThreadPoolExecutor類通過內(nèi)部類的形式提供了四種任務(wù)被拒絕時的處理器:AbortPolicy、CallerRunsPolicyDiscardOldestPolicyDiscardPolicy。

拒絕策略類 具體操作
AbortPolicy 拋出RejectedExecutionException異常,拒絕執(zhí)行任務(wù)
CallerRunsPolicy 在提交任務(wù)的線程執(zhí)行當(dāng)前任務(wù),即在調(diào)用函數(shù)executesubmit的線程直接運(yùn)行任務(wù)
DiscardOldestPolicy 直接取消當(dāng)前等待隊列中最早的任務(wù)
DiscardPolicy 以靜默方式丟棄任務(wù)

ThreadPoolExecutor默認(rèn)使用的是AbortPolicy處理策略,用戶可自行實(shí)現(xiàn)RejectedExecutionHandler接口自定義處理策略,本處不在贅述。

Executors對于ThreadPoolExecutor的創(chuàng)建

根據(jù)上文描述,Executors類提供了較多的關(guān)于創(chuàng)建或使用線程池的工具方法,此節(jié)重點(diǎn)總結(jié)其在創(chuàng)建ThreadPoolExecutor線程池的各方法。

newCachedThreadPool方法簇

newCachedThreadPool方法簇用于創(chuàng)建可緩存任務(wù)的ThreadPoolExecutor線程池。包括兩個重構(gòu)方法:

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                    60L, TimeUnit.SECONDS,
                                    new SynchronousQueue());
}
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                    60L, TimeUnit.SECONDS,
                                    new SynchronousQueue(),
                                    threadFactory);
}

結(jié)合上文分析的ThreadPoolExecutor各構(gòu)造參數(shù),可總結(jié)如下:

核心線程數(shù)為0:沒有核心線程,即在沒有任務(wù)運(yùn)行時所有線程均會被回收;

最大線程數(shù)為Integer.MAX_VALUE,即線程池中最大可存在的線程為Integer.MAX_VALUE,由于此值在通常情況下遠(yuǎn)遠(yuǎn)大于系統(tǒng)可新建的線程數(shù),可簡單理解為此線程池不限制最大可建的線程數(shù),此處可出現(xiàn)邏輯風(fēng)險,在提交任務(wù)時可能由于超過系統(tǒng)處理能力造成無法再新建線程時會出現(xiàn)OOM異常,提示無法創(chuàng)建新的線程;

存活時間60秒:線程數(shù)量超過核心線程后,空閑60秒的線程將會被回收,根據(jù)第一條可知核心線程數(shù)為0,則本條表示所有線程空閑超過60秒均會被回收;

等待隊列SynchronousQueue:構(gòu)建CachedThreadPool時,使用的等待隊列為SynchronousQueue類型,此類型的等待隊列較為特殊,可認(rèn)為這是一個容量為0的阻塞隊列,在調(diào)用其offer方法時,如當(dāng)前有消費(fèi)者正在等待獲取元素,則返回true,否則返回false。使用此等待隊列可做到快速提交任務(wù)到空閑線程,沒有空閑線程時觸發(fā)新建線程;

ThreadFactory參數(shù):默認(rèn)為DefaultThreadFactory,也可通過構(gòu)造函數(shù)設(shè)置。

newFixedThreadPool方法簇

newFixedThreadPool方法簇用于創(chuàng)建固定線程數(shù)的ThreadPoolExecutor線程池。包括兩個構(gòu)造方法:

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue());
}
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue(),
                                    threadFactory);
}

各構(gòu)造參數(shù)總結(jié):

核心線程數(shù)與最大線程數(shù)nThreads:構(gòu)建的ThreadPoolExecutor核心線程數(shù)與最大線程數(shù)相等且均為nThreads,這說明當(dāng)前線程池不會存在非核心線程,即不會存在線程的回收(allowCoreThreadTimeOut默認(rèn)為false),隨著任務(wù)的提交,線程數(shù)增加到nThreads個后就不會變化;

存活時間為0:線程存在非核心線程,該時間沒有特殊效果;

等待隊列LinkedBlockingQueue:該等待隊列為LinkedBlockingQueue類型,沒有長度限制;

ThreadFactory參數(shù):默認(rèn)為DefaultThreadFactory,也可通過構(gòu)造函數(shù)設(shè)置。

newSingleThreadExecutor方法簇

newSingleThreadExecutor方法簇用于創(chuàng)建只包含一個線程的線程池。包括兩個構(gòu)造方法:

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue()));
}
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue(),
                                threadFactory));
}

結(jié)合上文分析的ThreadPoolExecutor各構(gòu)造參數(shù),可總結(jié)如下:

核心線程數(shù)與最大線程數(shù)1:當(dāng)前線程池中有且僅有一個核心線程;

存活時間為0:當(dāng)前線程池不存在非核心線程,不會存在線程的超時回收;

等待隊列LinkedBlockingQueue:該等待隊列為LinkedBlockingQueue類型,沒有長度限制;

ThreadFactory參數(shù):默認(rèn)為DefaultThreadFactory,也可通過構(gòu)造函數(shù)設(shè)置。

特殊說明,函數(shù)實(shí)際返回的對象類型并不是ThreadPoolExecutor而是FinalizableDelegatedExecutorService類型,為何如此設(shè)計在后文統(tǒng)一討論。

三種常見線程池的對比

上文總結(jié)了Executors工具類創(chuàng)建常見線程池的方法,現(xiàn)對三種線程池區(qū)別進(jìn)行比較。

線程池類型 CachedThreadPool FixedThreadPool SingleThreadExecutor
核心線程數(shù) 0 nThreads(用戶設(shè)定) 1
最大線程數(shù) Integer.MAX_VALUE nThreads(用戶設(shè)定) 1
非核心線程存活時間 60s 無非核心線程 無非核心線程
等待隊列最大長度 1 無限制 無限制
特點(diǎn) 提交任務(wù)優(yōu)先復(fù)用空閑線程,沒有空閑線程則創(chuàng)建新線程 固定線程數(shù),等待運(yùn)行的任務(wù)均放入等待隊列 有且僅有一個線程在運(yùn)行,等待運(yùn)行任務(wù)放入等待隊列,可保證任務(wù)運(yùn)行順序與提交順序一直
內(nèi)存溢出 大量提交任務(wù)后,可能出現(xiàn)無法創(chuàng)建線程的OOM 大量提交任務(wù)后,可能出現(xiàn)內(nèi)存不足的OOM 大量提交任務(wù)后,可能出現(xiàn)內(nèi)存不足的OOM
三種類型的線程池與GC關(guān)系 原理說明

一般情況下JVM中的GC根據(jù)可達(dá)性分析確認(rèn)一個對象是否可被回收(eligible for GC),而在運(yùn)行的線程被視為‘GCRoot’。因此被在運(yùn)行的線程引用的對象是不會被GC回收的。在ThreadPoolExecutor類中具有f非靜態(tài)內(nèi)部類Worker,用于表示x當(dāng)前線程池中的線程,并且根據(jù)Java語言規(guī)范An instance i of a direct inner class C of a class or interface O is associated with an instance of O, known as the immediately enclosing instance of i. The immediately enclosing instance of an object, if any, is determined when the object is created (§15.9.2).可知非靜態(tài)內(nèi)部類對象具有外部包裝類對象的引用(此處也可通過查看字節(jié)碼來驗(yàn)證),因此Worker類的對象即作為線程對象(‘GCRoot’)有持有外部類ThreadPoolExecutor對象的引用,則在其運(yùn)行結(jié)束之前,外部內(nèi)不會被Gc回收。
根據(jù)以上分析,再次觀察以上三個線程池:

CachedThreadPool:沒有核心線程,且線程具有超時時間,可見在其引用消失后,等待任務(wù)運(yùn)行結(jié)束且所有線程空閑回收后,GC開始回收此線程池對象;

FixedThreadPool:核心線程數(shù)及最大線程數(shù)均為nThreads,并且在默認(rèn)allowCoreThreadTimeOutfalse的情況下,其引用消失后,核心線程即使空閑也不會被回收,故GC不會回收該線程池;

SingleThreadExecutor:默認(rèn)與FixedThreadPool情況一致,但由于其語義為單線程線程池,JDK開發(fā)人員為其提供了FinalizableDelegatedExecutorService包裝類,在創(chuàng)建FixedThreadPool對象時實(shí)際返回的是FinalizableDelegatedExecutorService對象,該對象持有FixedThreadPool對象的引用,但FixedThreadPool對象并不引用FinalizableDelegatedExecutorService對象,這使得在FinalizableDelegatedExecutorService對象的外部引用消失后,GC將會對其進(jìn)行回收,觸發(fā)finalize函數(shù),而該函數(shù)僅僅簡單的調(diào)用shutdown函數(shù)關(guān)閉線程,是的所有當(dāng)前的任務(wù)執(zhí)行完成后,回收線程池中線程,則GC可回收線程池對象。

因此可得出結(jié)論,CachedThreadPoolSingleThreadExecutor的對象在不顯式調(diào)用shutdown函數(shù)(或shutdownNow函數(shù)),且其對象引用消失的情況下,可以被GC回收FixedThreadPool對象在不顯式調(diào)用shutdown函數(shù)(或shutdownNow函數(shù)),且其對象引用消失的情況下不會被GC回收,會出現(xiàn)內(nèi)存泄露。

實(shí)驗(yàn)驗(yàn)證

以上結(jié)論可使用實(shí)驗(yàn)驗(yàn)證:

public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        //ExecutorService executorService = Executors.newFixedThreadPool(1);
        //ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.execute(() -> System.out.println(Thread.currentThread().getName()));
        //線程引用置空
        executorService = null;
        Runtime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("Shutdown.")));
        //等待線程超時,主要對CachedThreadPool有效
        Thread.sleep(100000);
        //手動觸發(fā)GC
        System.gc();
}

使用以上代碼,分別創(chuàng)建三種不同的線程池,可發(fā)現(xiàn)最終FixedThreadPool不會打印出‘Shutdown.’,JVM沒有退出。另外兩種線程池均能退出JVM。
因此無論使用什么線程池線程池使用完畢后均調(diào)用shutdown以保證其最終會被GC回收是一個較為安全的編程習(xí)慣。

猜想及踩坑代碼示例

根據(jù)以上的原理及代碼分析,很容易提出如下問題:既然SingleThreadExecutor的實(shí)現(xiàn)方式可以自動完成線程池的關(guān)閉,為何不使用同樣的方式實(shí)現(xiàn)FixedThreadPool呢?
目前作者沒有找到確切的原因,此處引用兩個對此有所討論的兩個網(wǎng)址:王智超-理解SingleThreadExecutor及[Why doesn"t all Executors factory methods wrap in a FinalizableDelegatedExecutorService?
](https://stackoverflow.com/que...。
作者當(dāng)前提出一種不保證正確的可能性:JDK開發(fā)人員可能重語義方面考慮將FixedThreadPool定義為可重新配置的線程池,SingleThreadExecutor定義為不可重新配置的線程池。因此沒有使用FinalizableDelegatedExecutorService對象包裝FixedThreadPool對象,將其控制權(quán)放到了程序員手中。
最后再分享一個關(guān)于SingleThreadExecutor的踩坑代碼,改代碼在編程過程中一般不會出現(xiàn),但其中涉及較多知識點(diǎn),不失為一個好的學(xué)習(xí)示例:

import java.util.concurrent.Callable;
import java.util.concurrent.Executors;

class Prog {
  public static void main(String[] args) {
    Callable callable = new Callable() {
      public Long call() throws Exception {
        // Allocate, to create some memory pressure.
        byte[][] bytes = new byte[1024][];
        for (int i = 0; i < 1024; i++) {
          bytes[i] = new byte[1024];
        }
        return 42L;
      }
    };
    for (;;) {
      Executors.newSingleThreadExecutor().submit(callable);
    }
  }
}

以上代碼在設(shè)置-Xmx128m的虛擬機(jī)進(jìn)行運(yùn)行,大概率會拋出RejectedExecutionException異常,其原理與上文分析的GC回收有關(guān),詳細(xì)分析可參考[Learning from bad code
](https://www.farside.org.uk/20...。

Executors對于ThreadPoolExecutor的創(chuàng)建的最佳實(shí)踐

以上總結(jié)了使用Executors創(chuàng)建常見線程池的方法,在簡單的使用中的確方便使用且減少的手動創(chuàng)建線程池的代碼量,但在真正開發(fā)高并發(fā)程序時,其默認(rèn)創(chuàng)建的線程由于屏蔽了底層參數(shù),程序員難以真正理解其中可能出現(xiàn)的細(xì)節(jié)問題,包括內(nèi)存溢出及拒絕策略等,故在使用中t推薦使用ThreadPoolExecutor等方式直接創(chuàng)建。此處可以參考《阿里巴巴Java開發(fā)手冊終極版v1.3.0》(六)并發(fā)處理的第4點(diǎn)。

總結(jié)

本文簡單總結(jié)了Java線程及常用線程池的使用,對比常見線程池的特點(diǎn)。由于本文側(cè)重于分析使用層面,并沒有深入探究各線程池具體的代碼實(shí)現(xiàn),此項可留后續(xù)繼續(xù)補(bǔ)充。

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/77197.html

相關(guān)文章

  • Java并發(fā)編程筆記(一)

    摘要:并發(fā)編程實(shí)戰(zhàn)水平很高,然而并不是本好書。一是多線程的控制,二是并發(fā)同步的管理。最后,使用和來關(guān)閉線程池,停止其中的線程。當(dāng)線程調(diào)用或等阻塞時,對這個線程調(diào)用會使線程醒來,并受到,且線程的中斷標(biāo)記被設(shè)置。 《Java并發(fā)編程實(shí)戰(zhàn)》水平很高,然而并不是本好書。組織混亂、長篇大論、難以消化,中文翻譯也較死板。這里是一篇批評此書的帖子,很是貼切。俗話說:看到有這么多人罵你,我就放心了。 然而知...

    cnsworder 評論0 收藏0
  • 美團(tuán)面試題:Java-線程 ThreadPool 專題詳解

    摘要:去美團(tuán)面試,問到了什么是線程池,如何使用,為什么要用以下做個總結(jié)。二線程池線程池的作用線程池作用就是限制系統(tǒng)中執(zhí)行線程的數(shù)量。真正的線程池接口是。創(chuàng)建固定大小的線程池。此線程池支持定時以及周期性執(zhí)行任務(wù)的需求。 去美團(tuán)面試,問到了什么是線程池,如何使用,為什么要用,以下做個總結(jié)。關(guān)于線程之前也寫過一篇文章《高級面試題總結(jié)—線程池還能這么玩?》 1、什么是線程池:? java.util...

    enrecul101 評論0 收藏0
  • 美團(tuán)面試題:Java-線程 ThreadPool 專題詳解

    摘要:去美團(tuán)面試,問到了什么是線程池,如何使用,為什么要用以下做個總結(jié)。二線程池線程池的作用線程池作用就是限制系統(tǒng)中執(zhí)行線程的數(shù)量。真正的線程池接口是。創(chuàng)建固定大小的線程池。此線程池支持定時以及周期性執(zhí)行任務(wù)的需求。 去美團(tuán)面試,問到了什么是線程池,如何使用,為什么要用,以下做個總結(jié)。關(guān)于線程之前也寫過一篇文章《高級面試題總結(jié)—線程池還能這么玩?》 1、什么是線程池:? java.util...

    wujl596 評論0 收藏0
  • Java SDK 并發(fā)包全面總結(jié)

    摘要:一和并發(fā)包中的和主要解決的是線程的互斥和同步問題,這兩者的配合使用,相當(dāng)于的使用。寫鎖與讀鎖之間互斥,一個線程在寫時,不允許讀操作。的注意事項不支持重入,即不可反復(fù)獲取同一把鎖。沒有返回值,也就是說無法獲取執(zhí)行結(jié)果。 一、Lock 和 Condition Java 并發(fā)包中的 Lock 和 Condition 主要解決的是線程的互斥和同步問題,這兩者的配合使用,相當(dāng)于 synchron...

    luckyyulin 評論0 收藏0
  • Java 總結(jié)

    摘要:中的詳解必修個多線程問題總結(jié)個多線程問題總結(jié)有哪些源代碼看了后讓你收獲很多,代碼思維和能力有較大的提升有哪些源代碼看了后讓你收獲很多,代碼思維和能力有較大的提升開源的運(yùn)行原理從虛擬機(jī)工作流程看運(yùn)行原理。 自己實(shí)現(xiàn)集合框架 (三): 單鏈表的實(shí)現(xiàn) 自己實(shí)現(xiàn)集合框架 (三): 單鏈表的實(shí)現(xiàn) 基于 POI 封裝 ExcelUtil 精簡的 Excel 導(dǎo)入導(dǎo)出 由于 poi 本身只是針對于 ...

    caspar 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<