黄色网址大全免费-黄色网址你懂得-黄色网址你懂的-黄色网址有那些-免费超爽视频-免费大片黄国产在线观看

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節(jié)點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 學(xué)習(xí)攻略 Java學(xué)習(xí) Java中的線程池

Java中的線程池

更新時間:2022-10-27 10:23:44 來源:動力節(jié)點 瀏覽3772次

服務(wù)器程序(如數(shù)據(jù)庫和 Web 服務(wù)器)重復(fù)執(zhí)行來自多個客戶端的請求,這些程序旨在處理大量短任務(wù)。構(gòu)建服務(wù)器應(yīng)用程序的一種方法是在每次請求到達(dá)時創(chuàng)建一個新線程,并在新創(chuàng)建的線程中為這個新請求提供服務(wù)。雖然這種方法實施起來似乎很簡單,但它也有明顯的缺點。與處理實際請求相比,為每個請求創(chuàng)建新線程的服務(wù)器將花費更多時間和消耗更多系統(tǒng)資源來創(chuàng)建和銷毀線程。

由于活動線程會消耗系統(tǒng)資源,同時創(chuàng)建過多線程的JVM會導(dǎo)致系統(tǒng)內(nèi)存不足。這就需要限制正在創(chuàng)建的線程數(shù)。

Java中的線程池是什么?

線程池重用先前創(chuàng)建的線程來執(zhí)行當(dāng)前任務(wù),并為線程周期開銷和資源抖動問題提供了解決方案。由于請求到達(dá)時線程已經(jīng)存在,因此消除了線程創(chuàng)建引入的延遲,使應(yīng)用程序更具響應(yīng)性。

Java 提供了以 Executor 接口為中心的 Executor 框架,它的子接口ExecutorService和實現(xiàn)這兩個接口的類ThreadPoolExecutor 。通過使用執(zhí)行器,只需實現(xiàn) Runnable 對象并將它們發(fā)送到執(zhí)行器執(zhí)行。

它們允許您利用線程,但專注于您希望線程執(zhí)行的任務(wù),而不是線程機制。

要使用線程池,我們首先創(chuàng)建一個 ExecutorService 對象并將一組任務(wù)傳遞給它。ThreadPoolExecutor 類允許設(shè)置核心和最大池大小。由特定線程運行的可運行對象按順序執(zhí)行。

線程池示例

在下面的教程中,我們將看一個線程池執(zhí)行器的基本示例——FixedThreadPool。

應(yīng)遵循的步驟

 

1.創(chuàng)建一個任務(wù)(Runnable Object)來執(zhí)行

2.使用Executors創(chuàng)建Executor Pool

3.將任務(wù)傳遞給Executor Pool

4. 關(guān)閉執(zhí)行器池

// Java program to illustrate
// ThreadPool
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
// Task class to be executed (Step 1)
class Task implements Runnable
{
	private String name;	
	public Task(String s)
	{
		name = s;
	}	
	// Prints task name and sleeps for 1s
	// This Whole process is repeated 5 times
	public void run()
	{
		try
		{
			for (int i = 0; i<=5; i++)
			{
				if (i==0)
				{
					Date d = new Date();
					SimpleDateFormat ft = new SimpleDateFormat("hh:mm:ss");
					System.out.println("Initialization Time for"
							+ " task name - "+ name +" = " +ft.format(d));
					//prints the initialization time for every task
				}
				else
				{
					Date d = new Date();
					SimpleDateFormat ft = new SimpleDateFormat("hh:mm:ss");
					System.out.println("Executing Time for task name - "+
							name +" = " +ft.format(d));
					// prints the execution time for every task
				}
				Thread.sleep(1000);
			}
			System.out.println(name+" complete");
		}		
		catch(InterruptedException e)
		{
			e.printStackTrace();
		}
	}
}
public class Test
{
	// Maximum number of threads in thread pool
	static final int MAX_T = 3;			
	public static void main(String[] args)
	{
		// creates five tasks
		Runnable r1 = new Task("task 1");
		Runnable r2 = new Task("task 2");
		Runnable r3 = new Task("task 3");
		Runnable r4 = new Task("task 4");
		Runnable r5 = new Task("task 5");			
		// creates a thread pool with MAX_T no. of
		// threads as the fixed pool size(Step 2)
		ExecutorService pool = Executors.newFixedThreadPool(MAX_T);		
		// passes the Task objects to the pool to execute (Step 3)
		pool.execute(r1);
		pool.execute(r2);
		pool.execute(r3);
		pool.execute(r4);
		pool.execute(r5);		
		// pool shutdown ( Step 4)
		pool.shutdown();	
	}
}

樣品執(zhí)行

輸出:
任務(wù)名稱的初始化時間 - 任務(wù) 2 = 02:32:56
任務(wù)名稱的初始化時間 - 任務(wù) 1 = 02:32:56
任務(wù)名稱的初始化時間 - 任務(wù) 3 = 02:32:56
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 1 = 02:32:57
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 2 = 02:32:57
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 3 = 02:32:57
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 1 = 02:32:58
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 2 = 02:32:58
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 3 = 02:32:58
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 1 = 02:32:59
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 2 = 02:32:59
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 3 = 02:32:59
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 1 = 02:33:00
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 3 = 02:33:00
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 2 = 02:33:00
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 2 = 02:33:01
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 1 = 02:33:01
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 3 = 02:33:01
任務(wù)2完成
任務(wù)1完成
任務(wù)3完成
任務(wù)名稱的初始化時間 - 任務(wù) 5 = 02:33:02
任務(wù)名稱的初始化時間 - 任務(wù) 4 = 02:33:02
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 4 = 02:33:03
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 5 = 02:33:03
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 5 = 02:33:04
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 4 = 02:33:04
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 4 = 02:33:05
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 5 = 02:33:05
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 5 = 02:33:06
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 4 = 02:33:06
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 5 = 02:33:07
任務(wù)名稱的執(zhí)行時間 - 任務(wù) 4 = 02:33:07
任務(wù)5完成
任務(wù)4完成

從程序的執(zhí)行中可以看出,只有當(dāng)池中的線程空閑時,才會執(zhí)行任務(wù) 4 或任務(wù) 5。在那之前,額外的任務(wù)被放置在一個隊列中。

使用這種方法的主要優(yōu)點之一是當(dāng)您希望一次處理 100 個請求,但又不想為相同的請求創(chuàng)建 100 個線程時,以減少 JVM 過載。您可以使用這種方法創(chuàng)建一個 10 個線程的 ThreadPool,您可以向該 ThreadPool 提交 100 個請求。

ThreadPool 將創(chuàng)建最多 10 個線程來一次處理 10 個請求。在任何單個線程處理完成后,

ThreadPool 會在內(nèi)部將第 11 個請求分配給這個 Thread

并將繼續(xù)對所有剩余的請求執(zhí)行相同的操作。

使用線程池的風(fēng)險

死鎖:

雖然死鎖可能發(fā)生在任何多線程程序中,但線程池引入了另一種死鎖情況,在這種情況下,由于線程不可用,所有正在執(zhí)行的線程都在等待隊列中等待的阻塞線程的結(jié)果。

線程泄漏:如果線程從池中刪除以執(zhí)行任務(wù)但在任務(wù)完成時沒有返回給它,則會發(fā)生線程泄漏。例如,如果線程拋出異常并且池類沒有捕捉到這個異常,那么線程將簡單地退出,將線程池的大小減少一。如果這種情況重復(fù)很多次,那么池最終會變空,并且沒有線程可用于執(zhí)行其他請求。

資源抖動:如果線程池大小非常大,那么在線程之間的上下文切換中浪費時間。正如解釋的那樣,擁有比最佳數(shù)量更多的線程可能會導(dǎo)致導(dǎo)致資源抖動的饑餓問題。

要點

不要將同時等待其他任務(wù)結(jié)果的任務(wù)排隊。這可能導(dǎo)致如上所述的死鎖情況。

使用線程進(jìn)行長期操作時要小心。這可能會導(dǎo)致線程永遠(yuǎn)等待并最終導(dǎo)致資源泄漏。

線程池必須在最后顯式結(jié)束。如果不這樣做,那么程序?qū)⒗^續(xù)執(zhí)行并且永遠(yuǎn)不會結(jié)束。在池上調(diào)用 shutdown() 以結(jié)束執(zhí)行程序。如果您在關(guān)閉后嘗試向執(zhí)行器發(fā)送另一個任務(wù),它將拋出 RejectedExecutionException。

需要了解有效調(diào)整線程池的任務(wù)。如果任務(wù)差異很大,那么為不同類型的任務(wù)使用不同的線程池以便正確調(diào)整它們是有意義的。

您可以限制可以在 JVM 中運行的最大線程數(shù),從而減少 JVM 內(nèi)存不足的機會。

如果您需要實現(xiàn)循環(huán)來創(chuàng)建新線程(Java線程創(chuàng)建方式)進(jìn)行處理,使用 ThreadPool 將有助于更快地處理,因為 ThreadPool 在達(dá)到最大限制后不會創(chuàng)建新線程。

Thread Processing 完成后,ThreadPool 可以使用同一個 Thread 做另一個進(jìn)程(這樣可以節(jié)省創(chuàng)建另一個 Thread 的時間和資源。)

調(diào)優(yōu)線程池

線程池的最佳大小取決于可用處理器的數(shù)量和任務(wù)的性質(zhì)。在一個只有計算類型進(jìn)程的隊列的 N 處理器系統(tǒng)上,最大線程池大小為 N 或 N+1 將實現(xiàn)最大效率。但是任務(wù)可能會等待 I/O,在這種情況下,我們會考慮比率請求的等待時間(W)和服務(wù)時間(S);導(dǎo)致最大池大小為 N*(1+ W/S) 以獲得最大效率。

線程池是組織服務(wù)器應(yīng)用程序的有用工具。它在概念上非常簡單,但是在實現(xiàn)和使用它時需要注意幾個問題,例如死鎖、資源抖動。使用執(zhí)行器服務(wù)更容易實現(xiàn)。

提交申請后,顧問老師會電話與您溝通安排學(xué)習(xí)

免費課程推薦 >>
技術(shù)文檔推薦 >>
主站蜘蛛池模板: 欧美激情二区 | 久久精选视频 | 日b在线观看 | 国产精品视频大全 | 国产一级特黄aa大片免费 | 欧美极品在线 | 国产91网 | 亚洲美日韩 | 成年人在线视频免费观看 | 国产成人精品福利站 | 一个人在线视频免费观看www | 下面一进一出好爽视频 | 亚洲人成在线免费观看 | 欧美xxx在线 | 成年视频xxxxx在线观看 | 亚洲一区二区三区久久久久 | 成人午夜在线观看国产 | 日本乱人伦片中文字幕三区 | 亚洲剧场午夜在线观看 | 成人gav| 日韩中文字幕免费版 | 国产一卡2卡3卡免费网站 | 日本一道免费一区二区三区 | 黄色免费在线视频 | 被多人强伦的小柔小说片段 | 女人色极影院 | 日韩美女一级毛片 | 久久久久久久网站 | 久久综合狠狠综合狠狠 | 麻豆一区二区三区在线观看 | 在线 中文字幕 日韩 欧美 | 日韩欧美在线不卡 | 日韩有码视频在线 | 手机在线观看毛片 | 天天影视色香欲综合网网站麻豆 | 久久91精品久久久久久水蜜桃 | 亚洲伊人成综合网 | 91免费视频软件 | 日xxxx| 在线播放性xxx欧美 在线播放你懂的 | 一级做a爱过程免费观看 |