国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

聊聊并發(fā)(五)——線程池

xiaochao / 1987人閱讀

摘要:線程池一種線程使用模式。線程池不僅能夠保證內(nèi)核的充分利用,還能防止過(guò)分調(diào)度。相關(guān)起提供了線程池相關(guān)頂級(jí)接口,及子接口和工具類。線程池的最大線程數(shù),要大于。可擴(kuò)容創(chuàng)建一個(gè)可根據(jù)需要線程數(shù),創(chuàng)建新的線程的線程池。

一、概述

1、介紹

  在使用線程時(shí),需要new一個(gè),用完了又要銷毀,這樣頻繁的創(chuàng)建和銷毀很耗資源,所以就提供了線程池。道理和連接池差不多,連接池是為了避免頻繁的創(chuàng)建和釋放連接,所以在連
接池中就有一定數(shù)量的連接,要用時(shí)從連接池拿出,用完歸還給連接池,線程池也一樣。
  線程池:一種線程使用模式。線程過(guò)多會(huì)帶來(lái)調(diào)度開銷,進(jìn)而影響緩存局部性和整體性能。而線程池維護(hù)著多
個(gè)線程,等待著監(jiān)督管理者分配可并發(fā)執(zhí)行的任務(wù)。這避免了在處理短時(shí)間任務(wù)時(shí)創(chuàng)建與銷毀線程的代價(jià)。線程池不僅能夠保證內(nèi)核的充分利用,還能防止過(guò)分調(diào)度。

  腦圖:https://www.processon.com/view/link/61849ba4f346fb2ecc4546e5

2、簡(jiǎn)單使用

  線程池用法很簡(jiǎn)單,?分為三步。首先用工具類Executors創(chuàng)建線程池,然后給線程池分配任務(wù),最后關(guān)閉線程池就行了。

 1 public class ThreadPoolTest { 2     public static void main(String[] args) throws Exception { 3  4         // 1.創(chuàng)建一個(gè) 10 個(gè)線程數(shù)的線程池 5         ExecutorService service = Executors.newFixedThreadPool(10); 6  7         // 2.執(zhí)行一個(gè)Runnable 8         service.execute(new Number1()); 9 10         // 2.提交一個(gè)Callable11         Future future = service.submit(new Number2());12         Integer integer = future.get();13         System.out.println("result = " + integer);14 15         // 關(guān)閉線程池16         service.shutdown();17     }18 }19 20 class Number1 implements Runnable {21 22     @Override23     public void run() {24         System.out.println("----打印Runnable----");25     }26 }27 28 // 10以內(nèi)數(shù)求和29 class Number2 implements Callable {30     private int sum = 0;31 32     @Override33     public Integer call() {34         for (int i = 0; i <= 10; i++) {35             if (i % 2 == 0) {36                 sum += i;37             }38         }39         return sum;40     }41 }

  注意:線程用完,要關(guān)閉線程池,否則程序依然在運(yùn)行中

3、相關(guān)API

  JDK 5.0 起提供了線程池相關(guān)API:頂級(jí)接口Executor,及子接口 ExecutorService 和工具類Executors。

  JUC包描述:圖片來(lái)源API文檔

  Executors:工具類,線程池的工廠類,用于創(chuàng)建并返回不同類型的線程池。

 1 // 一池N線程:創(chuàng)建一個(gè)固定(可重用)線程數(shù)的線程池。 2 ExecutorService Executors.newFixedThreadPool(int nThreads) 3  4 // 一池一線程:創(chuàng)建一個(gè)只有一個(gè)線程的線程池。 5 ExecutorService Executors.newSingleThreadExecutor() 6  7 // 可擴(kuò)容:創(chuàng)建一個(gè)可根據(jù)需要線程數(shù),創(chuàng)建新的線程的線程池。 8 ExecutorService Executors.newCachedThreadPool() 9 10 // 可用于調(diào)度:創(chuàng)建一個(gè)線程池,它可安排在給定延遲后運(yùn)行命令或者定期的執(zhí)行。11 ScheduledExecutorService Executors.newScheduledThreadPool(int corePoolSize)

  ExecutorService:

 1 // 執(zhí)行任務(wù)/命令,沒(méi)有返回值,一般用來(lái)執(zhí)行Runnable 2 void execute(Runnable command) 3  4 // 可用于提交一個(gè)Runnable,但沒(méi)有返回值 5 Future submit(Runnable task) 6  7 // 執(zhí)行任務(wù),有返回值,一般用來(lái)執(zhí)行Callable 8  Future submit(Callable task) 9 10 // 關(guān)閉連接池11 void shutdown()

4、使用舉例

  代碼示例:創(chuàng)建固定 5 個(gè)線程的線程池為 10 個(gè)任務(wù)服務(wù)。

 1 public class ThreadPoolTest { 2     public static void main(String[] args) { 3         // 1.創(chuàng)建一個(gè) 10 個(gè)線程數(shù)的線程池 4         ExecutorService service = Executors.newFixedThreadPool(5); 5  6         try { 7             for (int i = 0; i < 10; i++) { 8                 int finalI = i; 9                 service.execute(() -> {10 11                     System.out.println(Thread.currentThread().getName() + " 為客戶 " + finalI + " 辦理業(yè)務(wù)~");12 13 //                    try {14 //                        Thread.sleep(1000_000);15 //                    } catch (InterruptedException e) {16 //                        e.printStackTrace();17 //                    }18 19                 });20             }21         } finally {22             service.shutdown();23         }24     }25 }26 27 // 可能的一種結(jié)果28 pool-1-thread-1 為客戶 0 辦理業(yè)務(wù)~29 pool-1-thread-2 為客戶 1 辦理業(yè)務(wù)~30 pool-1-thread-2 為客戶 6 辦理業(yè)務(wù)~31 pool-1-thread-2 為客戶 7 辦理業(yè)務(wù)~32 pool-1-thread-2 為客戶 8 辦理業(yè)務(wù)~33 pool-1-thread-1 為客戶 5 辦理業(yè)務(wù)~34 pool-1-thread-2 為客戶 9 辦理業(yè)務(wù)~35 pool-1-thread-3 為客戶 2 辦理業(yè)務(wù)~36 pool-1-thread-4 為客戶 3 辦理業(yè)務(wù)~37 pool-1-thread-5 為客戶 4 辦理業(yè)務(wù)~

  可以看到,銀行 5 個(gè)窗口為 10 個(gè)客戶相繼服務(wù)。若前面服務(wù)時(shí)間長(zhǎng)(打開注釋),線程池便沒(méi)有新的線程來(lái)執(zhí)行任務(wù)了。程序會(huì)陷入等待中。
  代碼示例:創(chuàng)建單個(gè)線程的線程池為 10 個(gè)線程服務(wù)。代碼同上,只修改:

1 ExecutorService service = Executors.newSingleThreadExecutor();

  代碼示例:創(chuàng)建可擴(kuò)容線程的線程池為 10 個(gè)線程服務(wù)。代碼同上,只修改:

1 ExecutorService service = Executors.newCachedThreadPool();

5、線程池好處

  為什么要用線程池管理線程呢?當(dāng)然是為了線程復(fù)用。
  背景:經(jīng)常創(chuàng)建和銷毀、使用量特別大的資源,比如并發(fā)情況下的線程,對(duì)性能影響很大。
  思路:提前創(chuàng)建好多個(gè)線程,放入線程池中,使用時(shí)直接獲取,使用完放回池中。可以避免頻繁的創(chuàng)建和銷毀,實(shí)現(xiàn)重復(fù)利用。類似生活中的公共交通工具。
  好處:提高響應(yīng)速度(減少了創(chuàng)建新線程的時(shí)間);降低資源消耗(重復(fù)利用線程池中線程,不需要每次都創(chuàng)建);便于線程管理。

二、線程池設(shè)計(jì)與實(shí)現(xiàn)

1、介紹

  前面介紹了三種(固定數(shù)、單一的、可變的)創(chuàng)建線程池的方式,實(shí)際工作用哪一個(gè)呢?都不使用!為什么呢?
  《阿里巴巴Java開發(fā)手冊(cè)》明確規(guī)定:線程池不允許使用Executors創(chuàng)建,而是通過(guò)ThreadPoolExecutor的方式,規(guī)避資源耗盡風(fēng)險(xiǎn)。

  查看源碼,可以看到,用Executors創(chuàng)建線程池的三種方式中,都 new 了一個(gè) ThreadPoolExecutor。所以,實(shí)際生產(chǎn)一般通過(guò) ThreadPoolExecutor 的 7 個(gè)參數(shù),自定義線程池。
  源碼示例:7 個(gè)參數(shù)的構(gòu)造器。

 1 public ThreadPoolExecutor(int corePoolSize, 2                           int maximumPoolSize, 3                           long keepAliveTime, 4                           TimeUnit unit, 5                           BlockingQueue workQueue, 6                           ThreadFactory threadFactory, 7                           RejectedExecutionHandler handler) { 8     if (corePoolSize < 0 || 9         maximumPoolSize <= 0 ||10         maximumPoolSize < corePoolSize ||11         keepAliveTime < 0)12         throw new IllegalArgumentException();13     if (workQueue == null || threadFactory == null || handler == null)14         throw new NullPointerException();15     this.corePoolSize = corePoolSize;16     this.maximumPoolSize = maximumPoolSize;17     this.workQueue = workQueue;18     this.keepAliveTime = unit.toNanos(keepAliveTime);19     this.threadFactory = threadFactory;20     this.handler = handler;21 }

2、銀行服務(wù)

  介紹線程池之前,先來(lái)看一個(gè)生活中的案例。銀行業(yè)務(wù)辦理流程,如圖:

  某銀行一共有 5 個(gè)服務(wù)窗口,但平時(shí)一般只開放兩個(gè),另外三個(gè)不開放。大廳中還有 10 個(gè)等待服務(wù)的座位。某天:
  (1)客人1(用Thread1表示)來(lái)辦理業(yè)務(wù),他就直接去開放的窗口1辦理(假設(shè)他需要服務(wù)的時(shí)間很長(zhǎng),一直在服務(wù)中,后面的也一樣)。
  (2)Thread2來(lái)辦理業(yè)務(wù),由于窗口1在服務(wù)中,所以他去了開放的窗口2辦理。
  (3)Thread3來(lái)辦理業(yè)務(wù),由于窗口1和窗口2都在服務(wù)中,所以他去了大廳的等待服務(wù)座位上排隊(duì)等待。
  (4)Thread4~Thread12 同理Thread3。
  (5)Thread13來(lái)辦理業(yè)務(wù),由于窗口1和窗口2都在服務(wù)中,且此時(shí)大廳的等待座位上也已滿。銀行經(jīng)理便將關(guān)閉的窗口3打開來(lái)為Thread13服務(wù)。注意:這里并不是Thread13去大廳排隊(duì),然后隊(duì)列中隊(duì)頭元素Thread3出隊(duì)接受服務(wù)。而是直接為Thread13服務(wù)。
  (6)Thread14,Thread15來(lái)辦理業(yè)務(wù),會(huì)開放窗口4為Thread14服務(wù),開放窗口5為Thread15服務(wù)。
  (7)Thread16來(lái)辦理業(yè)務(wù),此時(shí),已無(wú)可用窗口,且大廳的等待座位上也已滿。銀行便拒絕再為 Thread16 服務(wù)。
  說(shuō)明:若 Thread13、Thread14、Thread15 業(yè)務(wù)辦理完畢后,沒(méi)有新的客人來(lái)銀行辦理業(yè)務(wù)。那么窗口3、窗口4、窗口5會(huì)在一定時(shí)間后又關(guān)閉起來(lái)。

3、核心參數(shù)(重要)

  下面介紹 ThreadPoolExecutor 構(gòu)造器中的 7 個(gè)核心參數(shù)。

  corePoolSize:線程池的核心線程數(shù)。
  maximumPoolSize:線程池的最大線程數(shù),要大于corePoolSize。
  keepAliveTime:非核心線程閑置下來(lái)最多存活的時(shí)間。
  unit:線程池中非核心線程保持存活的時(shí)間單位,與keepAliveTime一起使用。
  workQueue:用來(lái)保存提交后,等待執(zhí)行任務(wù)的阻塞隊(duì)列。
  threadFactory:創(chuàng)建線程的工廠類。
  handler:拒絕策略。

  在理解上一節(jié)"銀行服務(wù)"的過(guò)程后,就不難理解上面 7 個(gè)參數(shù)的含義。

  corePoolSize = 2:窗口1 + 窗口2。
  maximumPoolSize = 5:窗口1 + 窗口2 + 窗口3 + 窗口4 + 窗口5。
  workQueue = 10:銀行大廳排隊(duì)隊(duì)列的大小。關(guān)于阻塞隊(duì)列 BlockingQueue workQueue 請(qǐng)看這篇。
  keepAliveTime + unit:"窗口3、窗口4、窗口5會(huì)在一定時(shí)間后又關(guān)閉起來(lái)"的時(shí)間。
  handler:"銀行便拒絕再為 Thread16 服務(wù)"的拒絕方式。

  在了解 ThreadPoolExecutor 7個(gè)核心參數(shù)的作用后,再看Executors創(chuàng)建的三種線程池的源碼,就不難理解他們的作用。也就明白為什么《阿里巴巴Java開發(fā)手冊(cè)》中禁止使用Executors創(chuàng)建,而要使用ThreadPoolExecutor自定義線程池。
  源碼示例:
  一池N線程:創(chuàng)建一個(gè)固定(可重用)線程數(shù)的線程池。

 1 ExecutorService Executors.newFixedThreadPool(int nThreads); 2  3 public static ExecutorService newFixedThreadPool(int nThreads) { 4     return new ThreadPoolExecutor(nThreads, nThreads, 5                                   0L, TimeUnit.MILLISECONDS, 6                                   new LinkedBlockingQueue()); 7 } 8  9 public LinkedBlockingQueue() {10     this(Integer.MAX_VALUE);11 }

  一池一線程:創(chuàng)建一個(gè)只有一個(gè)線程的線程池。

 1 ExecutorService Executors.newSingleThreadExecutor(); 2  3 public static ExecutorService newSingleThreadExecutor() { 4     return new FinalizableDelegatedExecutorService 5         (new ThreadPoolExecutor(1, 1, 6                                 0L, TimeUnit.MILLISECONDS, 7                                 new LinkedBlockingQueue())); 8 } 9 10 public LinkedBlockingQueue() {11     this(Integer.MAX_VALUE);12 }

  可擴(kuò)容:創(chuàng)建一個(gè)可根據(jù)需要線程數(shù),創(chuàng)建新的線程的線程池。

1 ExecutorService Executors.newCachedThreadPool();2 3 public static ExecutorService newCachedThreadPool() {4     return new ThreadPoolExecutor(0, Integer.MAX_VALUE,5                                   60L, TimeUnit.SECONDS,6                                   new SynchronousQueue());7 }

4、工作流程(重要)

  在理解"銀行服務(wù)"的過(guò)程后,其實(shí)也就說(shuō)清楚了線程池的工作流程。只是一些細(xì)節(jié)沒(méi)有說(shuō),比如:
  (1)窗口3為Thread13服務(wù)完成后,Thread14才來(lái),情況如何?
  (2)……
  代碼示例:銀行 2+3 個(gè)窗口為陸續(xù)來(lái)的 16 個(gè)客戶服務(wù)。

 1 public class ThreadPoolDemo { 2     public static void main(String[] args) throws Exception { 3         // 模擬上圖中 2 + 3 + 10(大廳排隊(duì)長(zhǎng)度) 的線程池 4         ThreadPoolExecutor executor = new ThreadPoolExecutor( 5                 2, 5 6                 , 6, TimeUnit.SECONDS 7                 , new ArrayBlockingQueue<>(10) 8                 , Executors.defaultThreadFactory() 9                 , new ThreadPoolExecutor.AbortPolicy());10 11         // 創(chuàng)建16個(gè)線程模擬16個(gè)客戶12         final int num = 16;13         for (int i = 1; i <= num; i++) {14             int finalI = i;15 16             // 這里主要為了給線程起名字.17             Thread thread = new Thread(() -> {18                 System.out.println(Thread.currentThread().getName() + "=====" + finalI + " 號(hào)客人開始服務(wù)");19 20                 // 假設(shè) 13 和 16 服務(wù)很快.21                 if (finalI != 16 && finalI != 13) {22                     try {23                         // 正在為 finalI 號(hào)客戶服務(wù)中24                         Thread.sleep(1000_000);25                     } catch (InterruptedException e) {26                         e.printStackTrace();27                     }28                 }29 30                 System.out.println(Thread.currentThread().getName() + "=====" + finalI + " 號(hào)客人服務(wù)結(jié)束");31             }, "------" + i);32 33             System.out.println(thread.getName() + " 號(hào)客人來(lái)了");34             executor.execute(thread);35 36             // 讓主線程休息一下,保證上面開啟的線程先執(zhí)行.37             Thread.sleep(200);38         }39 40         // 保證上面的線程執(zhí)行完41         Thread.sleep(1_000);42 43         System.out.println("===核心線程數(shù)===" + executor.getCorePoolSize());44         System.out.println("===總?cè)蝿?wù)數(shù)=====" + executor.getTaskCount());45 46         final BlockingQueue queue = executor.getQueue();47         System.out.println("===正在排隊(duì)====" + queue.size());48 49         System.out.println("===最大線程數(shù)===" + executor.getMaximumPoolSize());50         System.out.println("==============" + executor.getPoolSize());51         System.out.println("===完成任務(wù)數(shù)===" + executor.getCompletedTaskCount());52         System.out.println("==============" + executor.getLargestPoolSize());53 54         executor.shutdown();55     }56 }57 58 // 結(jié)果(程序未停止)59 ------1 號(hào)客人來(lái)了60 pool-1-thread-1=====1 號(hào)客人開始服務(wù)61 ------2 號(hào)客人來(lái)了62 pool-1-thread-2=====2 號(hào)客人開始服務(wù)63 ------3 號(hào)客人來(lái)了64 ------4 號(hào)客人來(lái)了65 ------5 號(hào)客人來(lái)了66 ------6 號(hào)客人來(lái)了67 ------7 號(hào)客人來(lái)了68 ------8 號(hào)客人來(lái)了69 ------9 號(hào)客人來(lái)了70 ------10 號(hào)客人來(lái)了71 ------11 號(hào)客人來(lái)了72 ------12 號(hào)客人來(lái)了 // 到這里都不難理解73 ------13 號(hào)客人來(lái)了74 pool-1-thread-3=====13 號(hào)客人開始服務(wù)75 pool-1-thread-3=====13 號(hào)客人服務(wù)結(jié)束 // 開放窗口3為客戶13立刻服務(wù)完畢.76 pool-1-thread-3=====3 號(hào)客人開始服務(wù) // 阻塞隊(duì)列,隊(duì)頭 客戶3 出隊(duì)接受窗口3的服務(wù)77 ------14 號(hào)客人來(lái)了 // 加入阻塞隊(duì)列隊(duì)尾78 ------15 號(hào)客人來(lái)了79 pool-1-thread-4=====15 號(hào)客人開始服務(wù)80 ------16 號(hào)客人來(lái)了81 pool-1-thread-5=====16 號(hào)客人開始服務(wù)82 pool-1-thread-5=====16 號(hào)客人服務(wù)結(jié)束83 pool-1-thread-5=====4 號(hào)客人開始服務(wù)84 ===核心線程數(shù)===285 ===總?cè)蝿?wù)數(shù)=====1686 ===正在排隊(duì)====987 ===最大線程數(shù)===588 ==============589 ===完成任務(wù)數(shù)===290 ==============5

  其他的情況,可通過(guò)修改代碼示例中相關(guān)參數(shù)進(jìn)行測(cè)試,自然就理解。

5、如何配置線程數(shù)

  線程在Java中屬于稀缺資源,線程池不是越大越好,也不是越小越好。那么,線程池的參數(shù)要如何設(shè)置才合理呢?
  任務(wù)分為CPU密集型、IO密集型、混合型。
  CPU密集型:大部分都在用CPU跟內(nèi)存,加密,邏輯操作,業(yè)務(wù)處理等。
  IO密集型:數(shù)據(jù)庫(kù)鏈接,網(wǎng)絡(luò)通訊傳輸?shù)取?br>  CPU密集型:一般推薦線程池不要過(guò)大,一般是CPU數(shù) + 1,+1是因?yàn)榭赡艽嬖陧?yè)缺失(就是可能存在有些數(shù)據(jù)在硬盤中需要多來(lái)一個(gè)線程將數(shù)據(jù)讀入內(nèi)存)。如果線程池?cái)?shù)太大,可能會(huì)頻繁的進(jìn)行線程上下文切換跟任務(wù)調(diào)度。
  獲得當(dāng)前CPU核心數(shù)代碼如下:

1 Runtime.getRuntime().availableProcessors();

  IO密集型:線程數(shù)適當(dāng)大一點(diǎn),機(jī)器的CPU核心數(shù)*2。
  混合型:可以考慮根絕情況將它拆分成CPU密集型和IO密集型任務(wù),如果執(zhí)行時(shí)間相差不大,拆分可以提升吞吐量,反之沒(méi)有必要。

三、拒絕策略

1、介紹

  當(dāng)線程池的任務(wù)緩存隊(duì)列已滿并且線程池中的線程數(shù)目達(dá)到maximumPoolSize,如果還有任務(wù)到來(lái)就會(huì)采取任務(wù)拒絕策略,就會(huì)調(diào)用這個(gè)接口里的這個(gè)方法。也就是"銀行便拒絕再為 Thread16 服務(wù)"的拒絕方式。

1 public interface RejectedExecutionHandler {2     void rejectedExecution(Runnable r, ThreadPoolExecutor executor);3 }

2、4種拒絕策略

  ThreadPoolExecutor 提供了四種拒絕策略,分別是
  AbortPolicy:直接拋出異常,這也是默認(rèn)策略。
  CallerRunsPolicy:返回給調(diào)用者處理。用調(diào)用者所在線程來(lái)運(yùn)行任務(wù)。
  DiscardOldestPolicy:拋棄隊(duì)列中等待最久的任務(wù),然后把當(dāng)前任務(wù)加入隊(duì)列中嘗試再次提交當(dāng)前任務(wù)。
  DiscardPolicy:不處理,直接丟棄當(dāng)前任務(wù)。

  代碼示例:4種拒絕策略,代碼同上,只需修改:

 1 // 1.去掉這個(gè)if條件 2 if (finalI != 16 && finalI != 13) {} 3  4  5  6 // 2.1 線程池創(chuàng)建時(shí)拒絕策略為: 7 new ThreadPoolExecutor.AbortPolicy() 8 // 2.1 結(jié)果,直接拋出了異常.(只截取了最后一點(diǎn)) 9 ------16 號(hào)客人來(lái)了10 Exception in thread "main" java.util.concurrent.RejectedExecutionException11 12 13 14 // 2.2 線程池創(chuàng)建時(shí)拒絕策略為:15 new ThreadPoolExecutor.CallerRunsPolicy()16 // 2.2 結(jié)果,返回給調(diào)用者main處理了.(只截取了最后一點(diǎn))17 ------16 號(hào)客人來(lái)了18 main=====16 號(hào)客人開始服務(wù)19 20 21 22 // 2.3 線程池創(chuàng)建時(shí)拒絕策略為:23 new ThreadPoolExecutor.DiscardOldestPolicy()24 // 2.3 結(jié)果,見下圖25 26 27 28 // 2.4 線程池創(chuàng)建時(shí)拒絕策略為:29 new ThreadPoolExecutor.DiscardPolicy()30 // 2.4 結(jié)果(丟棄了任務(wù),沒(méi)有任何處理)

?

  通過(guò)debug斷點(diǎn)的方式,可以查看到:DiscardOldestPolicy策略中,此時(shí)阻塞隊(duì)列中是客戶4~客戶16。也就是客戶3 出隊(duì),被拋棄,客戶16入隊(duì)等待。

3、自定義拒絕策略

  如果不使用線程池提供的4種拒絕策略,也可以自己實(shí)現(xiàn)拒絕策略的接口,實(shí)現(xiàn)對(duì)這些超出數(shù)量的任務(wù)的處理。比如:為被拒絕的任務(wù)開啟一個(gè)新的線程執(zhí)行,如下。

 1 // 線程池創(chuàng)建時(shí)拒絕策略為: 2 new MyRejectedExecutionHandler() 3 // 結(jié)果 4 ------16 號(hào)客人來(lái)了 5 ---開啟新線程處理任務(wù)---=====16 號(hào)客人開始服務(wù) 6  7  8 // 自定義的策略拒絕 9 class MyRejectedExecutionHandler implements RejectedExecutionHandler {10 11     @Override12     public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {13         new Thread(r, "---開啟新線程處理任務(wù)---").start();14     }15 }

  參考文檔:https://www.matools.com/api/java8

  《阿里巴巴Java開發(fā)手冊(cè)》百度網(wǎng)盤:https://pan.baidu.com/s/1FZ9DNr0sF1mAc6Nq_6QZmg? ? 密碼: 4sw1

作者:Craftsman-L

本博客所有文章僅用于學(xué)習(xí)、研究和交流目的,版權(quán)歸作者所有,歡迎非商業(yè)性質(zhì)轉(zhuǎn)載。

如果本篇博客給您帶來(lái)幫助,請(qǐng)作者喝杯咖啡吧!點(diǎn)擊下面打賞,您的支持是我最大的動(dòng)力!

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/123754.html

相關(guān)文章

  • 聊聊面試中關(guān)于并發(fā)問(wèn)題的應(yīng)對(duì)方案

    摘要:這里呢,我直接給出高并發(fā)場(chǎng)景通常都會(huì)考慮的一些解決思路和手段結(jié)尾如何有效的準(zhǔn)備面試中并發(fā)類問(wèn)題,我已經(jīng)給出我的理解。 showImg(https://segmentfault.com/img/bV7Viy?w=550&h=405); 主題 又到面試季了,從群里,看到許多同學(xué)分享了自己的面試題目,我也抽空在網(wǎng)上搜索了一些許多公司使用的面試題,目前校招和社招的面試題基本都集中在幾個(gè)大方向上...

    xzavier 評(píng)論0 收藏0
  • 并發(fā) - 收藏集 - 掘金

    摘要:在中一般來(lái)說(shuō)通過(guò)來(lái)創(chuàng)建所需要的線程池,如高并發(fā)原理初探后端掘金閱前熱身為了更加形象的說(shuō)明同步異步阻塞非阻塞,我們以小明去買奶茶為例。 AbstractQueuedSynchronizer 超詳細(xì)原理解析 - 后端 - 掘金今天我們來(lái)研究學(xué)習(xí)一下AbstractQueuedSynchronizer類的相關(guān)原理,java.util.concurrent包中很多類都依賴于這個(gè)類所提供的隊(duì)列式...

    levius 評(píng)論0 收藏0
  • 并發(fā) - 收藏集 - 掘金

    摘要:在中一般來(lái)說(shuō)通過(guò)來(lái)創(chuàng)建所需要的線程池,如高并發(fā)原理初探后端掘金閱前熱身為了更加形象的說(shuō)明同步異步阻塞非阻塞,我們以小明去買奶茶為例。 AbstractQueuedSynchronizer 超詳細(xì)原理解析 - 后端 - 掘金今天我們來(lái)研究學(xué)習(xí)一下AbstractQueuedSynchronizer類的相關(guān)原理,java.util.concurrent包中很多類都依賴于這個(gè)類所提供的隊(duì)列式...

    fantix 評(píng)論0 收藏0
  • 后端ing

    摘要:當(dāng)活動(dòng)線程核心線程非核心線程達(dá)到這個(gè)數(shù)值后,后續(xù)任務(wù)將會(huì)根據(jù)來(lái)進(jìn)行拒絕策略處理。線程池工作原則當(dāng)線程池中線程數(shù)量小于則創(chuàng)建線程,并處理請(qǐng)求。當(dāng)線程池中的數(shù)量等于最大線程數(shù)時(shí)默默丟棄不能執(zhí)行的新加任務(wù),不報(bào)任何異常。 spring-cache使用記錄 spring-cache的使用記錄,坑點(diǎn)記錄以及采用的解決方案 深入分析 java 線程池的實(shí)現(xiàn)原理 在這篇文章中,作者有條不紊的將 ja...

    roadtogeek 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<