欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深度源碼解析Java 線程池的實(shí)現(xiàn)原理

 更新時(shí)間:2021年05月26日 10:58:27   作者:HollisChuang  
如何高效的使用這些資源就是程序員在平時(shí)寫代碼時(shí)候的一個(gè)努力的方向。本文要說的線程池就是一種對(duì) CPU 利用的優(yōu)化手段。對(duì)Java 線程池的實(shí)現(xiàn)原理相關(guān)知識(shí)感興趣的朋友一起看看吧

java 系統(tǒng)的運(yùn)行歸根到底是程序的運(yùn)行,程序的運(yùn)行歸根到底是代碼的執(zhí)行,代碼的執(zhí)行歸根到底是虛擬機(jī)的執(zhí)行,虛擬機(jī)的執(zhí)行其實(shí)就是操作系統(tǒng)的線程在執(zhí)行,并且會(huì)占用一定的系統(tǒng)資源,如CPU、內(nèi)存、磁盤、網(wǎng)絡(luò)等等。所以,如何高效的使用這些資源就是程序員在平時(shí)寫代碼時(shí)候的一個(gè)努力的方向。本文要說的線程池就是一種對(duì) CPU 利用的優(yōu)化手段。

線程池,百度百科是這么解釋的:

線程池是一種多線程處理形式,處理過程中將任務(wù)添加到隊(duì)列,然后在創(chuàng)建線程后自動(dòng)啟動(dòng)這些任務(wù)。線程池線程都是后臺(tái)線程。每個(gè)線程都使用默認(rèn)的堆棧大小,以默認(rèn)的優(yōu)先級(jí)運(yùn)行,并處于多線程單元中。如果某個(gè)線程在托管代碼中空閑(如正在等待某個(gè)事件),則線程池將插入另一個(gè)輔助線程來使所有處理器保持繁忙。如果所有線程池線程都始終保持繁忙,但隊(duì)列中包含掛起的工作,則線程池將在一段時(shí)間后創(chuàng)建另一個(gè)輔助線程但線程的數(shù)目永遠(yuǎn)不會(huì)超過最大值。超過最大值的線程可以排隊(duì),但他們要等到其他線程完成后才啟動(dòng)。

線程池,其實(shí)就是維護(hù)了很多線程的池子,類似這樣的技術(shù)還有很多的,例如:HttpClient 連接池、數(shù)據(jù)庫連接池、內(nèi)存池等等。

線程池的優(yōu)點(diǎn)

在 Java 并發(fā)編程框架中的線程池是運(yùn)用場景最多的技術(shù),幾乎所有需要異步或并發(fā)執(zhí)行任務(wù)的程序都可以使用線程池。在開發(fā)過程中,合理地使用線程池能夠帶來至少以下4個(gè)好處。

第一:降低資源消耗。通過重復(fù)利用已創(chuàng)建的線程降低線程創(chuàng)建和銷毀造成的消耗;

第二:提高響應(yīng)速度。當(dāng)任務(wù)到達(dá)時(shí),任務(wù)可以不需要等到線程創(chuàng)建就能立即執(zhí)行;

第三:提高線程的可管理性。線程是稀缺資源,如果無限制地創(chuàng)建,不僅會(huì)消耗系統(tǒng)資源,還會(huì)降低系統(tǒng)的穩(wěn)定性,使用線程池可以進(jìn)行統(tǒng)一分配、調(diào)優(yōu)和監(jiān)控。

第四:提供更強(qiáng)大的功能,比如延時(shí)定時(shí)線程池;

線程池的實(shí)現(xiàn)原理

當(dāng)向線程池提交一個(gè)任務(wù)之后,線程池是如何處理這個(gè)任務(wù)的呢?下面就先來看一下它的主要處理流程。先來看下面的這張圖,然后我們一步一步的來解釋。

當(dāng)使用者將一個(gè)任務(wù)提交到線程池以后,線程池是這么執(zhí)行的:

①首先判斷核心的線程數(shù)是否已滿,如果沒有滿,那么就去創(chuàng)建一個(gè)線程去執(zhí)行該任務(wù);否則請(qǐng)看下一步

②如果線程池的核心線程數(shù)已滿,那么就繼續(xù)判斷任務(wù)隊(duì)列是否已滿,如果沒滿,那么就將任務(wù)放到任務(wù)隊(duì)列中;否則請(qǐng)看下一步

③如果任務(wù)隊(duì)列已滿,那么就判斷線程池是否已滿,如果沒滿,那么就創(chuàng)建線程去執(zhí)行該任務(wù);否則請(qǐng)看下一步;

④如果線程池已滿,那么就根據(jù)拒絕策略來做出相應(yīng)的處理;

上面的四步其實(shí)就已經(jīng)將線程池的執(zhí)行原理描述結(jié)束了。如果不明白沒有關(guān)系,先一步一步往下看,上面涉及到的線程池的專有名詞都會(huì)詳細(xì)的介紹到。

我們?cè)谄綍r(shí)的開發(fā)中,線程池的使用基本都是基于ThreadPoolExexutor類,他的繼承體系是這樣子的:

那既然說在使用中都是基于ThreadPoolExecutor的那么我們就重點(diǎn)分析這個(gè)類。

至于他構(gòu)造體系中的其他的類或者是接口中的屬性,這里就不去截圖了,完全沒有必要。小伙伴如果實(shí)在想看就自己去打開代碼看一下就行了。

ThreadPoolExecutor

在《阿里巴巴 java 開發(fā)手冊(cè)》中指出了線程資源必須通過線程池提供,不允許在應(yīng)用中自行顯示的創(chuàng)建線程,這樣一方面是線程的創(chuàng)建更加規(guī)范,可以合理控制開辟線程的數(shù)量;另一方面線程的細(xì)節(jié)管理交給線程池處理,優(yōu)化了資源的開銷。

其原文描述如下:

ThreadPoolExecutor類中提供了四個(gè)構(gòu)造方法,但是他的四個(gè)構(gòu)造器中,實(shí)際上最終都會(huì)調(diào)用同一個(gè)構(gòu)造器,只不過是在另外三個(gè)構(gòu)造器中,如果有些參數(shù)不傳ThreadPoolExecutor會(huì)幫你使用默認(rèn)的參數(shù)。所以,我們直接來看這個(gè)完整參數(shù)的構(gòu)造器,來徹底剖析里面的參數(shù)。

public  class  ThreadPoolExecutor  extends  AbstractExecutorService {
    ......

    public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,long keepAliveTime,TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,
                                  RejectedExecutionHandler handler) {
            if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0){
                throw new IllegalArgumentException();
            }
            if (workQueue == null || threadFactory == null || handler == null){
                throw new NullPointerException();
            }
            this.acc = System.getSecurityManager() == null ? null : AccessController.getContext();
            this.corePoolSize = corePoolSize;
            this.maximumPoolSize = maximumPoolSize;
            this.workQueue = workQueue;
            this.keepAliveTime = unit.toNanos(keepAliveTime);
            this.threadFactory = threadFactory;
            this.handler = handler;
        }
}

主要參數(shù)就是下面這幾個(gè):

  • corePoolSize:線程池中的核心線程數(shù),包括空閑線程,也就是核心線程數(shù)的大小;
  • maximumPoolSize:線程池中允許的最多的線程數(shù),也就是說線程池中的線程數(shù)是不可能超過該值的;
  • keepAliveTime:當(dāng)線程池中的線程數(shù)大于 corePoolSize 的時(shí)候,在超過指定的時(shí)間之后就會(huì)將多出 corePoolSize 的的空閑的線程從線程池中刪除;
  • unit:keepAliveTime 參數(shù)的單位(常用的秒為單位);
  • workQueue:用于保存任務(wù)的隊(duì)列,此隊(duì)列僅保持由 executor 方法提交的任務(wù) Runnable 任務(wù);
  • threadFactory:線程池工廠,他主要是為了給線程起一個(gè)標(biāo)識(shí)。也就是為線程起一個(gè)具有意義的名稱;
  • handler:拒絕策略

阻塞隊(duì)列

workQueue 有多種選擇,在 JDK 中一共提供了 7 中阻塞對(duì)列,分別為:

  • ArrayBlockingQueue : 一個(gè)由數(shù)組結(jié)構(gòu)組成的有界阻塞隊(duì)列。 此隊(duì)列按照先進(jìn)先出(FIFO)的原則對(duì)元素進(jìn)行排序。默認(rèn)情況下不保證訪問者公平地訪問隊(duì)列 ,所謂公平訪問隊(duì)列是指阻塞的線程,可按照阻塞的先后順序訪問隊(duì)列。非公平性是對(duì)先等待的線程是不公平的,當(dāng)隊(duì)列可用時(shí),阻塞的線程都可以競爭訪問隊(duì)列的資格。
  • LinkedBlockingQueue : 一個(gè)由鏈表結(jié)構(gòu)組成的有界阻塞隊(duì)列。 此隊(duì)列的默認(rèn)和最大長度為Integer.MAX_VALUE。 此隊(duì)列按照先進(jìn)先出的原則對(duì)元素進(jìn)行排序。
  • PriorityBlockingQueue : 一個(gè)支持優(yōu)先級(jí)排序的無界阻塞隊(duì)列。 (雖然此隊(duì)列邏輯上是無界的,但是資源被耗盡時(shí)試圖執(zhí)行 add 操作也將失敗,導(dǎo)致 OutOfMemoryError)
  • DelayQueue: 一個(gè)使用優(yōu)先級(jí)隊(duì)列實(shí)現(xiàn)的無界阻塞隊(duì)列。 元素的一個(gè)無界阻塞隊(duì)列,只有在延遲期滿時(shí)才能從中提取元素
  • SynchronousQueue: 一個(gè)不存儲(chǔ)元素的阻塞隊(duì)列。 一種阻塞隊(duì)列,其中每個(gè)插入操作必須等待另一個(gè)線程的對(duì)應(yīng)移除操作 ,反之亦然。(SynchronousQueue 該隊(duì)列不保存元素)
  • LinkedTransferQueue: 一個(gè)由鏈表結(jié)構(gòu)組成的無界阻塞隊(duì)列。 相對(duì)于其他阻塞隊(duì)列LinkedTransferQueue多了tryTransfer和transfer方法。
  • LinkedBlockingDeque: 一個(gè)由鏈表結(jié)構(gòu)組成的雙向阻塞隊(duì)列。 是一個(gè)由鏈表結(jié)構(gòu)組成的雙向阻塞隊(duì)列

在以上的7個(gè)隊(duì)列中,線程池中常用的是ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue,

隊(duì)列中的常用的方法如下:

類型 方法 含義 特點(diǎn)
拋異常 add 添加一個(gè)元素 如果隊(duì)列滿,拋出異常 IllegalStateException
拋異常 remove 返回并刪除隊(duì)列的頭節(jié)點(diǎn) 如果隊(duì)列空,拋出異常 NoSuchElementException
拋異常 element 返回隊(duì)列頭節(jié)點(diǎn) 如果隊(duì)列空,拋出異常 NoSuchElementException
不拋異常,但是不阻塞 offer 添加一個(gè)元素 添加成功,返回 true,添加失敗,返回 false
不拋異常,但是不阻塞 poll 返回并刪除隊(duì)列的頭節(jié)點(diǎn) 如果隊(duì)列空,返回 null
不拋異常,但是不阻塞 peek 返回隊(duì)列頭節(jié)點(diǎn) 如果隊(duì)列空,返回 null
阻塞 put 添加一個(gè)元素 如果隊(duì)列滿,阻塞
阻塞 take 返回并刪除隊(duì)列的頭節(jié)點(diǎn) 如果隊(duì)列空,阻塞

關(guān)于阻塞隊(duì)列,介紹到這里也就基本差不多了。

線程池工廠

線程池工廠,就像上面已經(jīng)介紹的,目的是為了給線程起一個(gè)有意義的名字。用起來也非常的簡單,只需要實(shí)現(xiàn)ThreadFactory接口即可

public class CustomThreadFactory implements ThreadFactory {
    @Override
    public Thread newThread(Runnable r) {
        Thread thread = new Thread(r);
        thread.setName("我是你們自己定義的線程名稱");
        return thread;
    }
}

具體的使用就不去廢話了。

拒絕策略

線程池有四種默認(rèn)的拒絕策略,分別為:

  • AbortPolicy:這是線程池默認(rèn)的拒絕策略,在任務(wù)不能再提交的時(shí)候,拋出異常,及時(shí)反饋程序運(yùn)行狀態(tài)。如果是比較關(guān)鍵的業(yè)務(wù),推薦使用此拒絕策略,這樣子在系統(tǒng)不能承載更大的并發(fā)量的時(shí)候,能夠及時(shí)的通過異常發(fā)現(xiàn);
  • DiscardPolicy:丟棄任務(wù),但是不拋出異常。如果線程隊(duì)列已滿,則后續(xù)提交的任務(wù)都會(huì)被丟棄,且是靜默丟棄。這玩意不建議使用;
  • DiscardOldestPolicy:丟棄隊(duì)列最前面的任務(wù),然后重新提交被拒絕的任務(wù)。這玩意不建議使用;
  • CallerRunsPolicy:如果任務(wù)添加失敗,那么主線程就會(huì)自己調(diào)用執(zhí)行器中的 executor 方法來執(zhí)行該任務(wù)。這玩意不建議使用;

也就是說關(guān)于線程池的拒絕策略,最好使用默認(rèn)的。這樣能夠及時(shí)發(fā)現(xiàn)異常。如果上面的都不能滿足你的需求,你也可以自定義拒絕策略,只需要實(shí)現(xiàn) RejectedExecutionHandler 接口即可

public class CustomRejection implements RejectedExecutionHandler {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        System.out.println("你自己想怎么處理就怎么處理");
    }
}

看到這里,我們?cè)賮懋嬕粡垐D來總結(jié)和概括下線程池的執(zhí)行示意圖:

詳細(xì)的執(zhí)行過程全部在圖中說明了。

提交任務(wù)到線程池

在 java 中,有兩個(gè)方法可以將任務(wù)提交到線程池,分別是submitexecute

execute 方法

execute()方法用于提交不需要返回值的任務(wù),所以無法判斷任務(wù)是否被線程池執(zhí)行成功。

void execute(Runnable command);

通過以下代碼可知 execute() 方法輸入的任務(wù)是一個(gè)Runnable類的實(shí)例。

executorService.execute(()->{
            System.out.println("ThreadPoolDemo.execute");
        });

submit 方法

submit()方法用于提交需要返回值的任務(wù)。

Future<?> submit(Runnable task);

線程池會(huì)返回一個(gè)future類型的對(duì)象,通過這個(gè) future 對(duì)象可以判斷任務(wù)是否執(zhí)行成功,并且可以通過future的get()方法來獲取返回值,get() 方法會(huì)阻塞當(dāng)前線程直到任務(wù)完成,而使用get(long timeout,TimeUnit unit)方法則會(huì)阻塞當(dāng)前線程一段時(shí)間后立即返回,這時(shí)候有可能任務(wù)沒有執(zhí)行完。

Future<?> submit = executorService.submit(() -> {
            System.out.println("ThreadPoolDemo.submit");
        });

關(guān)閉線程池

其實(shí),如果優(yōu)雅的關(guān)閉線程池是一個(gè)令人頭疼的問題,線程開啟是簡單的,但是想要停止卻不是那么容易的。通常而言, 大部分程序員都是使用 jdk 提供的兩個(gè)方法來關(guān)閉線程池,他們分別是:shutdownshutdownNow;

通過調(diào)用線程池的 shutdownshutdownNow 方法來關(guān)閉線程池。它們的原理是遍歷線程池中的工作線程,然后逐個(gè)調(diào)用線程的 interrupt 方法來中斷線程(PS:中斷,僅僅是給線程打上一個(gè)標(biāo)記,并不是代表這個(gè)線程停止了,如果線程不響應(yīng)中斷,那么這個(gè)標(biāo)記將毫無作用),所以無法響應(yīng)中斷的任務(wù)可能永遠(yuǎn)無法終止。

但是它們存在一定的區(qū)別,shutdownNow首先將線程池的狀態(tài)設(shè)置成 STOP,然后嘗試停止所有的正在執(zhí)行或暫停任務(wù)的線程,并返回等待執(zhí)行任務(wù)的列表,而 shutdown 只是將線程池的狀態(tài)設(shè)置成SHUTDOWN狀態(tài),然后中斷所有沒有正在執(zhí)行任務(wù)的線程。

只要調(diào)用了這兩個(gè)關(guān)閉方法中的任意一個(gè),isShutdown 方法就會(huì)返回 true。當(dāng)所有的任務(wù)都已關(guān)閉后,才表示線程池關(guān)閉成功,這時(shí)調(diào)用isTerminaed方法會(huì)返回 true。至于應(yīng)該調(diào)用哪一種方法來關(guān)閉線程池,應(yīng)該由提交到線程池的任務(wù)特性決定,通常調(diào)用 shutdown方法來關(guān)閉線程池,如果任務(wù)不一定要執(zhí)行完,則可以調(diào)用 shutdownNow 方法。

這里推薦使用穩(wěn)妥的 shutdownNow 來關(guān)閉線程池,至于更優(yōu)雅的方式我會(huì)在以后的并發(fā)編程設(shè)計(jì)模式中的兩階段終止模式中會(huì)再次詳細(xì)介紹。

合理的參數(shù)

為什么叫合理的參數(shù),那不合理的參數(shù)是什么樣子的?在我們創(chuàng)建線程池的時(shí)候,里面的參數(shù)該如何設(shè)置才能稱之為合理呢?其實(shí)這是有一定的依據(jù)的,我們先來看一下以下的創(chuàng)建的方式:

ExecutorService executorService = new ThreadPoolExecutor(5,
                5,
                5,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5),
                r -> {
                    Thread thread = new Thread(r);
                    thread.setName("線程池原理講解");
                    return thread;
                });

你說他合理不合理?我也不知道,因?yàn)槲覀儧]有參考的依據(jù),在實(shí)際的開發(fā)中,我們需要根據(jù)任務(wù)的性質(zhì)(IO是否頻繁?)來決定我們創(chuàng)建的核心的線程數(shù)的大小,實(shí)際上可以從以下的一個(gè)角度來分析:

  • 任務(wù)的性質(zhì):CPU密集型任務(wù)、IO密集型任務(wù)和混合型任務(wù);
  • 任務(wù)的優(yōu)先級(jí):高、中和低;
  • 任務(wù)的執(zhí)行時(shí)間:長、中和短;
  • 任務(wù)的依賴性:是否依賴其他系統(tǒng)資源,如數(shù)據(jù)庫連接;

性質(zhì)不同的任務(wù)可以用不同規(guī)模的線程池分開處理。分為CPU密集型和IO密集型。

CPU密集型任務(wù)應(yīng)配置盡可能小的線程,如配置 Ncpu+1個(gè)線程的線程池。(可以通過Runtime.getRuntime().availableProcessors()來獲取CPU物理核數(shù))

IO密集型任務(wù)線程并不是一直在執(zhí)行任務(wù),則應(yīng)配置盡可能多的線程,如 2*Ncpu

混合型的任務(wù),如果可以拆分,將其拆分成一個(gè)CPU密集型任務(wù)一個(gè)IO密集型任務(wù),只要這兩個(gè)任務(wù)執(zhí)行的時(shí)間相差不是太大,那么分解后執(zhí)行的吞吐量將高于串行執(zhí)行的吞吐量。

如果這兩個(gè)任務(wù)執(zhí)行時(shí)間相差太大,則沒必要進(jìn)行分解??梢酝ㄟ^ Runtime.getRuntime().availableProcessors() 方法獲得當(dāng)前設(shè)備的CPU個(gè)數(shù)。

優(yōu)先級(jí)不同的任務(wù)可以使用優(yōu)先級(jí)隊(duì)列 PriorityBlockingQueue來處理。它可以讓優(yōu)先級(jí)高的任務(wù)先執(zhí)行(注意:如果一直有優(yōu)先級(jí)高的任務(wù)提交到隊(duì)列里,那么優(yōu)先級(jí)低的任務(wù)可能永遠(yuǎn)不能執(zhí)行)

執(zhí)行時(shí)間不同的任務(wù)可以交給不同規(guī)模的線程池來處理,或者可以使用優(yōu)先級(jí)隊(duì)列,讓執(zhí)行時(shí)間短的任務(wù)先執(zhí)行。依賴數(shù)據(jù)庫連接池的任務(wù),因?yàn)榫€程提交SQL后需要等待數(shù)據(jù)庫返回結(jié)果,等待的時(shí)間越長,則 CPU 空閑時(shí)間就越長,那么線程數(shù)應(yīng)該設(shè)置得越大,這樣才能更好地利用CPU。

建議使用有界隊(duì)列。有界隊(duì)列能增加系統(tǒng)的穩(wěn)定性和預(yù)警能力,可以根據(jù)需要設(shè)大一點(diǎn)。方式因?yàn)樘峤坏娜蝿?wù)過多而導(dǎo)致 OOM;

7、本文小結(jié)

本文主要介紹的是線程池的實(shí)現(xiàn)原理以及一些使用技巧,在實(shí)際開發(fā)中,線程池可以說是稍微高級(jí)一點(diǎn)的程序員的必備技能。所以掌握好線程池這門技術(shù)也是重中之重!

以上就是深度源碼解析Java 線程池的實(shí)現(xiàn)原理的詳細(xì)內(nèi)容,更多關(guān)于Java 線程池的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • mybatis if傳入字符串?dāng)?shù)字踩坑記錄及解決

    mybatis if傳入字符串?dāng)?shù)字踩坑記錄及解決

    這篇文章主要介紹了mybatis if傳入字符串?dāng)?shù)字踩坑記錄及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Spring Security  整體架構(gòu)操作流程

    Spring Security  整體架構(gòu)操作流程

    這篇文章主要介紹了Spring Security  整體架構(gòu)操作流程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-07-07
  • commons fileupload實(shí)現(xiàn)文件上傳的實(shí)例代碼

    commons fileupload實(shí)現(xiàn)文件上傳的實(shí)例代碼

    這篇文章主要介紹了commons fileupload實(shí)現(xiàn)文件上傳的實(shí)例代碼,包括文件上傳的原理分析等相關(guān)知識(shí)點(diǎn),本文給大家介紹的非常詳細(xì),具有參考借鑒價(jià)值,感興趣的朋友一起看看吧
    2016-10-10
  • springBoot?@Scheduled實(shí)現(xiàn)多個(gè)任務(wù)同時(shí)開始執(zhí)行

    springBoot?@Scheduled實(shí)現(xiàn)多個(gè)任務(wù)同時(shí)開始執(zhí)行

    這篇文章主要介紹了springBoot?@Scheduled實(shí)現(xiàn)多個(gè)任務(wù)同時(shí)開始執(zhí)行,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java項(xiàng)目如何引入日志生成器及其日志分級(jí)

    Java項(xiàng)目如何引入日志生成器及其日志分級(jí)

    這篇文章主要介紹了Java項(xiàng)目引入日志生成器及其日志分級(jí),本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • Java StringBuilder類原理及常用方法

    Java StringBuilder類原理及常用方法

    這篇文章主要介紹了Java StringBuilder類原理及常用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • springMVC利用FastJson接口返回json數(shù)據(jù)相關(guān)配置詳解

    springMVC利用FastJson接口返回json數(shù)據(jù)相關(guān)配置詳解

    本篇文章主要介紹了springMVC利用FastJson接口返回json數(shù)據(jù)相關(guān)配置詳解,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • Eclipse 安裝 SVN 在線插件教程

    Eclipse 安裝 SVN 在線插件教程

    這篇文章主要介紹了Eclipse 安裝 SVN 在線插件教程的相關(guān)資料,這里對(duì)安裝步驟進(jìn)行了詳細(xì)介紹,需要的朋友可以參考下
    2016-11-11
  • Netty分布式ByteBuf使用命中緩存的分配解析

    Netty分布式ByteBuf使用命中緩存的分配解析

    這篇文章主要為大家介紹了Netty分布式ByteBuf?使用命中緩存的分配解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • Java8新特性stream和parallelStream區(qū)別

    Java8新特性stream和parallelStream區(qū)別

    這篇文章主要介紹了Java8新特性stream和parallelStream區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11

最新評(píng)論