日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java线程详解(11)-线程池

發布時間:2025/3/21 java 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java线程详解(11)-线程池 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Sun在Java5中,對Java線程的類庫做了大量的擴展,其中線程池就是Java5的新特征之一,除了線程池之外,還有很多多線程相關的內容,為多線程的編程帶來了極大便利。為了編寫高效穩定可靠的多線程程序,線程部分的新增內容顯得尤為重要。

????????有關Java5線程新特征的內容全部在java.util.concurrent下面,里面包含數目眾多的接口和類,熟悉這部分API特征是一項艱難的學習過程。目前有關這方面的資料和書籍都少之又少,大所屬介紹線程方面書籍還停留在java5之前的知識層面上。

????????當然新特征對做多線程程序沒有必須的關系,在java5之前通用可以寫出很優秀的多線程程序。只是代價不一樣而已。

????????線程池的基本思想還是一種對象池的思想,開辟一塊內存空間,里面存放了眾多(未死亡)的線程,池中線程執行調度由池管理器來處理。當有線程任務時,從池中取一個,執行完成后線程對象歸池,這樣可以避免反復創建線程對象所帶來的性能開銷,節省了系統的資源。

????????在Java5之前,要實現一個線程池是相當有難度的,現在Java5為我們做好了一切,我們只需要按照提供的API來使用,即可享受線程池帶來的極大便利。

????????Java5的線程池分好多種:固定尺寸的線程池、單任務線程池、可變尺寸連接池、延遲連接池、單任務延遲連接池、自定義線程池。

????????在使用線程池之前,必須知道如何去創建一個線程池,在Java5中,需要了解的是java.util.concurrent.Executors類的API,這個類提供大量創建連接池的靜態方法,是必須掌握的。

一、固定大小的線程池

import?java.util.concurrent.ExecutorService;?? import?java.util.concurrent.Executors;??/**?*?Java線程:線程池?*/?? public?class?Test?{??public?static?void?main(String[]?args)?{??//創建一個可重用固定線程數的線程池??ExecutorService?pool?=Executors.newFixedThreadPool(2);??//創建實現了Runnable接口對象,Thread對象當然也實現了Runnable接口??Thread?t1?=?new?MyThread();??Thread?t2?=?new?MyThread();??Thread?t3?=?new?MyThread();??Thread?t4?=?new?MyThread();??Thread?t5?=?new?MyThread();??//將線程放入線程池中進行執行??pool.execute(t1);??pool.execute(t2);??pool.execute(t3);??pool.execute(t4);??pool.execute(t5);??//關閉線程池??pool.shutdown();??}?? }?? class?MyThread?extends?Thread{??public?void?run(){??System.out.println(Thread.currentThread().getName()+"正在執行...");??}?? }??


????????執行結果:

pool-1-thread-1正在執行...?? pool-1-thread-2正在執行...?? pool-1-thread-2正在執行...?? pool-1-thread-2正在執行...?? pool-1-thread-1正在執行...??


二、單任務線程池

? ? ? ? 在上例的基礎上改一行創建pool對象的代碼為:

//創建一個使用單個?worker線程的?Executor,以無界隊列方式來運行該線程。?? ExecutorService?pool=Executors.newSingleThreadExecutor();??


????????執行結果:

pool-1-thread-1正在執行...?? pool-1-thread-1正在執行...?? pool-1-thread-1正在執行...?? pool-1-thread-1正在執行...?? pool-1-thread-1正在執行...??


????????對于以上兩種連接池,大小都是固定的,當要加入的池的線程(或者任務)超過池最大尺寸時候,則入此線程池需要排隊等待。

????????一旦池中有線程完畢,則排隊等待的某個線程會入池執行。

?

三、可變尺寸的線程池

? ? ? ? 與上面的類似,只是改動下pool的創建方式:

//創建一個可根據需要創建新線程的線程池,但是在以前構造的線程可用時將重用它們。?? ExecutorService?pool=Executors.newCachedThreadPool();??


????????執行結果:

pool-1-thread-2正在執行...?? pool-1-thread-4正在執行...?? pool-1-thread-1正在執行...?? pool-1-thread-3正在執行...?? pool-1-thread-5正在執行...??


四、延遲連接池

import?java.util.concurrent.Executors;?? import?java.util.concurrent.ScheduledExecutorService;?? import?java.util.concurrent.TimeUnit;??/**?*?Java線程:線程池?*/?? public?class?Test?{??public?static?void?main(String[]?args)?{??//創建一個線程池,它可安排在給定延遲后運行命令或者定期地執行。??ScheduledExecutorServicepool=Executors.newScheduledThreadPool(2);??//創建實現了Runnable接口對象,Thread對象當然也實現了Runnable接口??Threadt1?=?new?MyThread();??Threadt2?=?new?MyThread();??Thread?t3?=?new?MyThread();??Thread?t4?=?new?MyThread();??Thread?t5?=?new?MyThread();??//將線程放入線程池中進行執行??pool.execute(t1);??pool.execute(t2);??pool.execute(t3);??//使用延遲執行風格的方法??pool.schedule(t4,?10,?TimeUnit.MILLISECONDS);??pool.schedule(t5,?10,?TimeUnit.MILLISECONDS);??//關閉線程池??pool.shutdown();??}?? }?? class?MyThread?extends?Thread{??public?void?run(){??System.out.println(Thread.currentThread().getName()+"正在執行...");??}?? }??


????????執行結果:

pool-1-thread-1正在執行...?? pool-1-thread-1正在執行...?? pool-1-thread-1正在執行...?? pool-1-thread-1正在執行...?? pool-1-thread-2正在執行...??


五、單任務延遲連接池

????????在四代碼基礎上,做改動

//創建一個單任務執行線程池,它可安排在給定延遲后運行命令或者定期地執行。?? ScheduledExecutorServicepool=Executors.newSingleThreadScheduledExecutor();??


????????執行結果:

pool-1-thread-1正在執行...?? pool-1-thread-1正在執行...?? pool-1-thread-1正在執行...?? pool-1-thread-1正在執行...?? pool-1-thread-1正在執行...??


六、自定義線程池

import?java.util.concurrent.ArrayBlockingQueue;?? import?java.util.concurrent.BlockingQueue;?? import?java.util.concurrent.ThreadPoolExecutor;?? import?java.util.concurrent.TimeUnit;??/**?*?Java線程:線程池-自定義線程池?*/?? public?class?Test?{??public?static?void?main(String[]?args)?{??//創建等待隊列??BlockingQueue<Runnable>?bqueue=newArrayBlockingQueue<Runnable>(20);??//創建一個單線程執行任務,它可安排在給定延遲后運行命令或者定期地執行。??ThreadPoolExecutor?pool=newThreadPoolExecutor(2,?3,?2,?TimeUnit.MILLISECONDS,?bqueue);??//創建實現了Runnable接口對象,Thread對象當然也實現了Runnable接口??Thread?t1?=?new?MyThread();??Thread?t2?=?new?MyThread();??Thread?t3?=?new?MyThread();??Thread?t4?=?new?MyThread();??Thread?t5?=?new?MyThread();??Thread?t6?=?new?MyThread();??Thread?t7?=?new?MyThread();??//將線程放入線程池中進行執行??pool.execute(t1);??pool.execute(t2);??pool.execute(t3);??pool.execute(t4);??pool.execute(t5);??pool.execute(t6);??pool.execute(t7);??//關閉線程池??pool.shutdown();??}?? }?? class?MyThread?extends?Thread{??public?void?run(){??System.out.println(Thread.currentThread().getName()+"正在執行...");??try?{??Thread.sleep(100L);??}?catch?(InterruptedException?e)?{??e.printStackTrace();??}??}?? }??


????????執行結果:

pool-1-thread-1正在執行...?? pool-1-thread-2正在執行...?? pool-1-thread-1正在執行...?? pool-1-thread-2正在執行...?? pool-1-thread-1正在執行...?? pool-1-thread-2正在執行...?? pool-1-thread-1正在執行...??


????????創建自定義線程池的構造方法很多,本例中參數ThreadPoolExecutor的含義如下:

public?ThreadPoolExecutor(int?corePoolSize,??int?maximumPoolSize,??long?keepAliveTime,??TimeUnit?unit,??BlockingQueue<Runnable>?workQueue)??


????????用給定的初始參數和默認的線程工廠及處理程序創建新的ThreadPoolExecutor。使用Executors工廠方法之一比使用此通用構造方法方便得多。

????????參數:

corePoolSize?-池中所保存的線程數,包括空閑線程。?? maximumPoolSize?-池中允許的最大線程數。?? keepAliveTime?-當線程數大于核心時,此為終止前多余的空閑線程等待新任務的最長時間。?? unit?-keepAliveTime參數的時間單位。?? workQueue?-執行前用于保持任務的隊列。此隊列僅保持由execute方法提交的Runnable任務。?

?
????????拋出:IllegalArgumentException

如果?corePoolSize或?keepAliveTime小于零,或者?maximumPoolSize小于或等于零,或者?corePoolSize大于?maximumPoolSize。??
NullPointerException-如果workQueue為?null?自定義連接池稍微麻煩些,不過通過創建的ThreadPoolExecutor線程池對象,可以獲取到當前線程池的尺寸、正在執行任務的線程數、工作隊列等等。??
?

總結

以上是生活随笔為你收集整理的Java线程详解(11)-线程池的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。