java線程池和線程實例化_淺談Java 線程池原理及使用方式

一、簡介

什么是線程池?

池的概念大家也許都有所聽聞,池就是相當于一個容器,里面有許許多多的東西你可以即拿即用。java中有線程池、連接池等等。線程池就是在系統啟動或者實例化池時創建一些空閑的線程,等待工作調度,執行完任務后,線程并不會立即被銷毀,而是重新處于空閑狀態,等待下一次調度。

線程池的工作機制?

在線程池的編程模式中,任務提交并不是直接提交給線程,而是提交給池。線程池在拿到任務之后,就會尋找有沒有空閑的線程,有則分配給空閑線程執行,暫時沒有則會進入等待隊列,繼續等待空閑線程。如果超出最大接受的工作數量,則會觸發線程池的拒絕策略。

為什么使用線程池?

線程的創建與銷毀需要消耗大量資源,重復的創建與銷毀明顯不必要。而且池的好處就是響應快,需要的時候自取,就不會存在等待創建的時間。線程池可以很好地管理系統內部的線程,如數量以及調度。

二、常用線程池介紹

Java類ExecutorService是線程池的父接口,并非頂層接口。以下四種常用線程池的類型都可以是ExecutorService。

單一線程池?Executors.newSingleThreadExecutor()

內部只有唯一一個線程進行工作調度,可以保證任務的執行順序(FIFO,LIFO)

package com.test;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class PoolTest {

public static void main(String[] args) {

// 創建單一線程池

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

List list = new ArrayList();

list.add("first");

list.add("second");

list.add("third");

list.forEach(o -> {

// 遍歷集合提交任務

singleThreadExecutor.execute(new Runnable() {

@Override

public void run() {

System.out.println(Thread.currentThread().getName() + " : " + o);

try {

// 間隔1s

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

});

});

}

}

執行結果:

pool-1-thread-1 : first

pool-1-thread-1 : second

pool-1-thread-1 : third

可緩存線程池 Executors.newCachedThreadPool()

如果線程池中有可使用的線程,則使用,如果沒有,則在池中新建一個線程,可緩存線程池中線程數量最大為Integer.MAX_VALUE。通常用它來運行一些執行時間短,且經常用到的任務。

package com.test;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class PoolTest {

public static void main(String[] args) {

// 創建可緩存線程池

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

List list = new ArrayList();

list.add("first");

list.add("second");

list.add("third");

list.forEach(o -> {

try {

// 間隔3s

Thread.sleep(3000);

} catch (InterruptedException e) {

e.printStackTrace();

}

// 遍歷集合提交任務

cachedThreadPool.execute(new Runnable() {

@Override

public void run() {

System.out.println(Thread.currentThread().getName() + " : " + o);

try {

// 間隔1s

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

});

});

}

}

執行結果:

pool-1-thread-1 : first

pool-1-thread-1 : second

pool-1-thread-1 : third

因為間隔時間長,下一個任務運行時,上一個任務已經完成,所以線程可以繼續復用,如果間隔時間調短,那么部分線程將會使用新線程來運行。

把每個任務等待時間從3s調低至1s:

執行結果:

pool-1-thread-1 : first

pool-1-thread-2 : second

pool-1-thread-1 : third

定長線程池?Executors.newFixedThreadPool(int nThreads)

創建一個固定線程數量的線程池,參數手動傳入

package com.test;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class PoolTest {

public static void main(String[] args) {

// 創建可緩存線程池

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);

List list = new ArrayList();

list.add("first");

list.add("second");

list.add("third");

list.add("fourth");

list.forEach(o -> {

try {

// 間隔1s

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

// 遍歷集合提交任務

fixedThreadPool.execute(new Runnable() {

@Override

public void run() {

System.out.println(Thread.currentThread().getName() + " : " + o);

try {

// 間隔1s

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

});

});

}

}

執行結果:

pool-1-thread-1 : first

pool-1-thread-2 : second

pool-1-thread-3 : third

pool-1-thread-1 : fourth

定時線程池 Executors.newScheduledThreadPool(int corePoolSize)

創建一個定長線程池,支持定時及周期性任務執行

package com.test;

import java.util.concurrent.Executors;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;

public class PoolTest {

public static void main(String[] args) {

// 創建定長線程池、支持定時、延遲、周期性執行任務

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);

scheduledThreadPool.scheduleAtFixedRate(new Runnable() {

@Override

public void run() {

System.out.println(Thread.currentThread().getName() + " : 1秒后每隔3秒執行一次");

}

}, 1, 3, TimeUnit.SECONDS);

}

}

執行結果:

pool-1-thread-1 : 1秒后每隔3秒執行一次

pool-1-thread-1 : 1秒后每隔3秒執行一次

pool-1-thread-2 : 1秒后每隔3秒執行一次

pool-1-thread-2 : 1秒后每隔3秒執行一次

pool-1-thread-2 : 1秒后每隔3秒執行一次

pool-1-thread-2 : 1秒后每隔3秒執行一次

pool-1-thread-2 : 1秒后每隔3秒執行一次

三、自定義線程池

常用構造函數:

ThreadPoolExecutor(int corePoolSize,?int maximumPoolSize,?long keepAliveTime,?TimeUnit unit,?BlockingQueue workQueue)

參數說明:

1、corePoolSize 核心線程數大小,當線程數

2、maximumPoolSize 最大線程數, 當線程數 >= corePoolSize的時候,會把runnable放入workQueue中

3、keepAliveTime ?保持存活時間,當線程數大于corePoolSize的空閑線程能保持的最大時間。

4、unit 時間單位

5、workQueue 保存任務的阻塞隊列

6、threadFactory 創建線程的工廠

7、handler 拒絕策略

任務執行順序:

1、當線程數小于corePoolSize時,創建線程執行任務。

2、當線程數大于等于corePoolSize并且workQueue沒有滿時,放入workQueue中

3、線程數大于等于corePoolSize并且當workQueue滿時,新任務新建線程運行,線程總數要小于maximumPoolSize

4、當線程總數等于maximumPoolSize并且workQueue滿了的時候執行handler的rejectedExecution。也就是拒絕策略。

ThreadPoolExecutor默認有四個拒絕策略:

1、new ThreadPoolExecutor.AbortPolicy() ? 直接拋出異常RejectedExecutionException

2、new ThreadPoolExecutor.CallerRunsPolicy()????直接調用run方法并且阻塞執行

3、new ThreadPoolExecutor.DiscardPolicy() ? 直接丟棄后來的任務

4、new ThreadPoolExecutor.DiscardOldestPolicy() ?丟棄在隊列中隊首的任務

緩沖隊列BlockingQueue:

BlockingQueue是雙緩沖隊列。BlockingQueue內部使用兩條隊列,允許兩個線程同時向隊列一個存儲,一個取出操作。在保證并發安全的同時,提高了隊列的存取效率。

常用的幾種BlockingQueue:

ArrayBlockingQueue(int i):規定大小的BlockingQueue,其構造必須指定大小。其所含的對象是FIFO順序排序的。

LinkedBlockingQueue()或者(int i):大小不固定的BlockingQueue,若其構造時指定大小,生成的BlockingQueue有大小限制,不指定大小,其大小有Integer.MAX_VALUE來決定。其所含的對象是FIFO順序排序的。

PriorityBlockingQueue()或者(int i):類似于LinkedBlockingQueue,但是其所含對象的排序不是FIFO,而是依據對象的自然順序或者構造函數的Comparator決定。

SynchronizedQueue():特殊的BlockingQueue,對其的操作必須是放和取交替完成。

package com.test;

import java.util.concurrent.LinkedBlockingDeque;

import java.util.concurrent.RejectedExecutionHandler;

import java.util.concurrent.ThreadPoolExecutor;

import java.util.concurrent.TimeUnit;

public class PoolTest {

public static void main(String[] args) {

// 工作隊列

LinkedBlockingDeque workQueue = new LinkedBlockingDeque();

// 拒絕策略

RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 10, 20, TimeUnit.MILLISECONDS, workQueue, handler);

threadPoolExecutor.execute(new Runnable() {

@Override

public void run() {

System.out.println("自定義線程池");

}

});

}

}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/271167.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/271167.shtml
英文地址,請注明出處:http://en.pswp.cn/news/271167.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

線性代數及其應用_線性代數入門——行列式的簡單應用選講

系列簡介:這個系列文章講解線性代數的基礎內容,注重學習方法的培養。線性代數課程的一個重要特點(也是難點)是概念眾多,而且各概念間有著千絲萬縷的聯系,對于初學者不易理解的問題我們會不惜筆墨加以解釋。在內容上,以…

RocketMQ 使用及常見問題

前言 本文檔是針對RocketMQ使用及常見問題的說明。 一.獲取項目、安裝包及文檔 1. alibaba/RocketMQ https://github.com/alibaba/RocketMQ 2. Download the latest release package https://github.com/alibaba/RocketMQ/releases 3.…

系統開發基礎:UML相關知識筆記

1、UML概念統一建模語言(Unified Modeling Language UML)是面向對象軟件的標準建模語言。由于簡單、統一,又能夠表達軟件設計中的動態和靜態信息。目前UML已經成為可視化建模語言的工業標準。2、UML的組成UML三要素:構造塊、規則、…

java中什么是運行異常_在java中最常用的運行時異常是什么?

我從不會拋出NullPointerException。對我來說,它是一個出現在代碼中當出現問題時,需要開發人員看看會發生什么。然后(s)他固定的原因,它不會再次發生。我使用IllegalStateException表示對象配置不正確或調用的順序不正確。但是,我…

迭代器 java_面試必備(含答案):30 個 Java 高頻面試問題

Java集合框架為Java編程語言的基礎,也是Java面試中很重要的一個知識點。這里,我列出了一些關于Java集合的重要問題和答案。1.Java集合框架是什么?說出一些集合框架的優點?每種編程語言中都有集合,最初的Java版本包含幾…

硬件基礎:臺式電腦上的常用的幾個接口!

今天給大家詳細講解臺式電腦上的常用的幾個接口!1、I/O接口部分下圖所有的接口,也是我們機箱后面的接口,統稱為:I/O接口。2、鍵鼠PS/2PS/2接口是I/O接口中比較常見的一種接口,用來連接鍵盤和鼠標,二者可以用…

CSS-DOM介紹

三位一體的網頁: 我們在瀏覽器里看到的網頁其實是由以下三層信息構成的一個共同體: 1、結構層: 結構層是由HTML和XHTML之類的標記語言所構成的。所就是哪些出現在html標簽里面的單詞,對網頁內容的語義含義作出了如下描述&#xff0c;例如&#xff0c;<p>This is a paragr…

java 開發注意項_JAVA開發注意事項集錦

本篇博客用于持續記錄開發過程中的常用的需要注意的事項&#xff0c;都是嚴重的生產問題大家總結出來的、記得持續更新喔。一&#xff0c;不要以時間戳作為唯一健時間戳精確到ms級別&#xff0c;并不能作為唯一入口參數&#xff0c;數據庫更新唯一查詢參數&#xff0c;唯一健需…

系統開發基礎:UML中圖的相關知識筆記(上)

1、圖的概念圖(Diagram) 是一組元素的圖形表示&#xff0c;大多數情況下&#xff0c;把圖畫成頂點&#xff08;代表事物&#xff09;和弧(表示關系)的連通圖。2、UML中圖的分類UML2.0中的圖主要有&#xff1a;類圖、對象圖、用例圖、序列圖、通信圖、狀態圖、活動圖、構件圖、部…

python循環頂帖_設計Python數據庫連接池1-對象的循環引用問題

在Python中如果對象定義了__del__方法的話&#xff0c;在對象的引用記數為0時會自動調用__del__方法(很象c中的析構函數)&#xff0c;但如果A對象引用B對象&#xff0c;B對象又引用A對象&#xff0c;就形成循環引用&#xff0c;此時A&#xff0c;B對象引用次數都為1。python就無…

編譯時類型 和運行時類型的 區別(1)

class T{ void f(int x){ System.out.println("int in T:" x); } void f(double x){ System.out.println("double in T:"x); } void f(Object x){ System.out.println("Object in T:" x); }} class S extends T{ void f(int x){  //子類覆蓋基…

系統開發基礎:UML中圖的相關知識筆記(下)

1、狀態圖狀態圖展現了一個狀態機&#xff0c;它由狀態、轉換、事件、活動組成。狀態圖關注系統的動態視圖&#xff0c;它對于接口、類、協作的行為建模尤為重要&#xff0c;它強調對象行為的事件順序。組成&#xff1a;簡單狀態、組合狀態、轉換&#xff08;事件和動作&#x…

java京東左側固定層_京東首頁右側固定層

需求說明制作京東首頁右側的固定層&#xff0c;6個圖標&#xff1a;京東會員、購物車、我的關注、我的足跡、我的消息和咨詢JIMI默認狀態下僅顯示圖標&#xff0c;背景顏色為深灰色&#xff1b;當鼠標移至圖標上時&#xff0c;背景顏色為深紅色&#xff0c;并且顯示文本css*{ma…

云開發技術應用python_云開發技術應用(Python)

本書共14章&#xff0c;從Python語言的語法特性開始&#xff0c;介紹了Python的安裝和配置、數據類型及表達式、流程控制、序列和字典、文件處理、函數等&#xff0c;由淺入深&#xff0c;循序漸進&#xff0c;逐步引入高級話題&#xff0c;包括面向對象編程、模塊和包、異常處…

記錄下Linux難記實用的命令

1 看文件大小&#xff1a;du -sm * | sort -n 2 合并多個文件&#xff0c;可以跨文件夾合并&#xff1a;cat *_.txt >> news.txt 3 給文件改編碼&#xff1a;iconv -f GBK -t UTF-8 原文件名 -o 新文件名 4 查找文件內容&#xff1a;grep "thermcontact" */*.i…

系統設計基礎:系統設計基本任務相關知識

1、系統設計的目的提前為系統指定藍圖&#xff0c;在各種技術和實施方法中進行權衡&#xff0c;精心設計&#xff0c;合理利用各種資源、最終確定新系統的詳細設計方案。2、系統設計的內容系統設計的內容主要包括系統總體結構設計、代碼設計、輸出設計、輸入設計、處理過程設計…

java7 3dm下載_3DM游戲運行庫合集安裝包v2.8

游戲運行庫大全 游戲運行環境 所有游戲組件 32位 64位系統常用運行庫合集 3DM游戲常用運行庫安裝包 下載 幸姨作品本安裝包集成32位和64位運行庫&#xff0c;是目前互聯網上最新最全的常用運行庫合集&#xff0c;能自動識別系統版本以提供適合您的組件&#xff0c;無人值守自動…