大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 學習攻略 Java學習 Java線程池的使用示例

Java線程池的使用示例

更新時間:2022-04-11 11:01:11 來源:動力節點 瀏覽7127次

Java中的線程池是什么?

動力節點小編來為大家講解,Java線程池重用先前創建的線程來執行當前任務,并為線程周期開銷和資源抖動問題提供了解決方案。由于請求到達時線程已經存在,因此消除了線程創建引入的延遲,使應用程序更具響應性。

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

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

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

執行器線程池方法

Method                         Description
newFixedThreadPool(int)           Creates a fixed size thread pool.
newCachedThreadPool()             Creates a thread pool that creates new 
                                  threads as needed, but will reuse previously 
                                  constructed threads when they are available
newSingleThreadExecutor()         Creates a single thread. 

在固定線程池的情況下,如果執行器當前正在運行所有線程,則將掛起的任務放入隊列中,并在線程空閑時執行。

線程池示例

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

應遵循的步驟

 

1.創建一個任務(Runnable Object)來執行

2.使用Executors創建Executor Pool

3.將任務傳遞給Executor Pool

4.關閉Executor Pool

// 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();	
	}
}

樣品執行

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

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

使用線程池的風險

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

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

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

要點

不要將同時等待其他任務結果的任務排隊。這可能導致如上所述的死鎖情況。

使用線程進行長期操作時要小心。這可能會導致線程永遠等待并最終導致資源泄漏。

線程池必須在最后顯式結束。如果不這樣做,那么程序將繼續執行并且永遠不會結束。在池上調用 shutdown() 以結束執行程序。如果您在關閉后嘗試向執行器發送另一個任務,它將拋出 RejectedExecutionException。

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

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

如果您需要實現循環來創建新線程進行處理,使用 ThreadPool 將有助于更快地處理,因為 ThreadPool 在達到最大限制后不會創建線程

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

調優線程池

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

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

提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 91正在播放极品白嫩在线观看 | 蕾丝视频在线看片国产 | 高清亚洲综合色成在线播放放 | 国产亚洲精品一品区99热 | 久久久久亚洲香蕉网 | 伊人网址 | 亚洲精品第一区二区在线 | 国产欧美精品 | 国产99r视频精品免费观看 | 久久精品国产色蜜蜜麻豆 | 亚洲欧美韩日 | 涩涩伊人 | 日本色综合 | 久久精品一区二区三区四区 | 国产精品一区三区 | 男人的天堂视频在线 | 久久r热这里有精品视频 | 四虎影院免费观看视频 | 国产精品久久久久免费a∨ 国产精品久久久久免费视频 | 免费一级a毛片在线播放视 免费一级成人毛片 | 欧美高清亚洲欧美一区h | 国产在线视频资源 | 国产精品网站在线观看 | 草久在线 | 国产九九热 | 免费看成人播放毛片 | 青草青草久热精品视频99 | 亚洲精品美女国产一区 | 五月天在线免费视频 | 99香蕉国产精品偷在线观看 | www.四虎影院在线观看 | 久久久亚洲国产精品主播 | 在线国产网站 | 国产精品a区 | 色爱区综合| 成人黄色在线视频 | 夜色综合| 黄色毛片免费在线观看 | 91日本在线精品高清观看 | 日韩在线操 | 免费看成人毛片日本久久 |