① java實現通用線程池
線程池通俗的描述就是預先創建若干空閑線程 等到需要用多線程去處理事務的時候去喚醒某些空閑線程執行處理任務 這樣就省去了頻繁創建線程的時間 因為頻 繁創建線程是要耗費大量的CPU資源的 如果一個應用程序需要頻繁地處理大量並發事務 不斷的創建銷毀線程往往會大大地降低系統的效率 這時候線程池就派 上用場了
本文旨在使用Java語言編寫一個通用的線程池 當需要使用線程池處理事務時 只需按照指定規范封裝好事務處理對象 然後用已有的線程池對象去自動選擇空 閑線程自動調用事務處理對象即可 並實現線程池的動態修改(修改當前線程數 最大線程數等) 下面是實現代碼
//ThreadTask java
package polarman threadpool;
/** *//**
*線程任務
* @author ryang
*
*/
public interface ThreadTask {
public void run();
}
//PooledThread java
package polarman threadpool;
import java util Collection; import java util Vector;
/** *//**
*接受線程池管理的線程
* @author ryang
*
*/
public class PooledThread extends Thread {
protected Vector tasks = new Vector();
protected boolean running = false;
protected boolean stopped = false;
protected boolean paused = false;
protected boolean killed = false;
private ThreadPool pool;
public PooledThread(ThreadPool pool) { this pool = pool;
}
public void putTask(ThreadTask task) { tasks add(task);
}
public void putTasks(ThreadTask[] tasks) { for(int i= ; i<tasks length; i++) this tasks add(tasks[i]);
}
public void putTasks(Collection tasks) { this tasks addAll(tasks);
}
protected ThreadTask popTask() { if(tasks size() > ) return (ThreadTask)tasks remove( );
else
return null;
}
public boolean isRunning() {
return running;
}
public void stopTasks() {
stopped = true;
}
public void stopTasksSync() {
stopTasks();
while(isRunning()) { try {
sleep( );
} catch (InterruptedException e) {
}
}
}
public void pauseTasks() {
paused = true;
}
public void pauseTasksSync() {
pauseTasks();
while(isRunning()) { try {
sleep( );
} catch (InterruptedException e) {
}
}
}
public void kill() { if(!running)
interrupt();
else
killed = true;
}
public void killSync() {
kill();
while(isAlive()) { try {
sleep( );
} catch (InterruptedException e) {
}
}
}
public synchronized void startTasks() {
running = true;
this notify();
}
public synchronized void run() { try { while(true) { if(!running || tasks size() == ) { pool notifyForIdleThread(); //System out println(Thread currentThread() getId() + : 空閑 ); this wait(); }else {
ThreadTask task;
while((task = popTask()) != null) { task run(); if(stopped) {
stopped = false;
if(tasks size() > ) { tasks clear(); System out println(Thread currentThread() getId() + : Tasks are stopped );
break;
}
}
if(paused) {
paused = false;
if(tasks size() > ) { System out println(Thread currentThread() getId() + : Tasks are paused );
break;
}
}
}
running = false;
}
if(killed) {
killed = false;
break;
}
}
}catch(InterruptedException e) {
return;
}
//System out println(Thread currentThread() getId() + : Killed );
}
}
//ThreadPool java
package polarman threadpool;
import java util Collection; import java util Iterator; import java util Vector;
/** *//**
*線程池
* @author ryang
*
*/
public class ThreadPool {
protected int maxPoolSize;
protected int initPoolSize;
protected Vector threads = new Vector();
protected boolean initialized = false;
protected boolean hasIdleThread = false;
public ThreadPool(int maxPoolSize int initPoolSize) { this maxPoolSize = maxPoolSize; this initPoolSize = initPoolSize;
}
public void init() {
initialized = true;
for(int i= ; i<initPoolSize; i++) {
PooledThread thread = new PooledThread(this);
thread start(); threads add(thread);
}
//System out println( 線程池初始化結束 線程數= + threads size() + 最大線程數= + maxPoolSize);
}
public void setMaxPoolSize(int maxPoolSize) { //System out println( 重設最大線程數 最大線程數= + maxPoolSize); this maxPoolSize = maxPoolSize;
if(maxPoolSize < getPoolSize())
setPoolSize(maxPoolSize);
}
/** *//**
*重設當前線程數
* 若需殺掉某線程 線程不會立刻殺掉 而會等到線程中的事務處理完成* 但此方法會立刻從線程池中移除該線程 不會等待事務處理結束
* @param size
*/
public void setPoolSize(int size) { if(!initialized) {
initPoolSize = size;
return;
}else if(size > getPoolSize()) { for(int i=getPoolSize(); i<size && i<maxPoolSize; i++) {
PooledThread thread = new PooledThread(this);
thread start(); threads add(thread);
}
}else if(size < getPoolSize()) { while(getPoolSize() > size) { PooledThread th = (PooledThread)threads remove( ); th kill();
}
}
//System out println( 重設線程數 線程數= + threads size());
}
public int getPoolSize() { return threads size();
}
protected void notifyForIdleThread() {
hasIdleThread = true;
}
protected boolean waitForIdleThread() {
hasIdleThread = false;
while(!hasIdleThread && getPoolSize() >= maxPoolSize) { try { Thread sleep( ); } catch (InterruptedException e) {
return false;
}
}
return true;
}
public synchronized PooledThread getIdleThread() { while(true) { for(Iterator itr=erator(); itr hasNext();) { PooledThread th = (PooledThread)itr next(); if(!th isRunning())
return th;
}
if(getPoolSize() < maxPoolSize) {
PooledThread thread = new PooledThread(this);
thread start(); threads add(thread);
return thread;
}
//System out println( 線程池已滿 等待 );
if(waitForIdleThread() == false)
return null;
}
}
public void processTask(ThreadTask task) {
PooledThread th = getIdleThread();
if(th != null) { th putTask(task); th startTasks();
}
}
public void processTasksInSingleThread(ThreadTask[] tasks) {
PooledThread th = getIdleThread();
if(th != null) { th putTasks(tasks); th startTasks();
}
}
public void processTasksInSingleThread(Collection tasks) {
PooledThread th = getIdleThread();
if(th != null) { th putTasks(tasks); th startTasks();
}
}
}
下面是線程池的測試程序
//ThreadPoolTest java
import java io BufferedReader; import java io IOException; import java io InputStreamReader;
import polarman threadpool ThreadPool; import polarman threadpool ThreadTask;
public class ThreadPoolTest {
public static void main(String[] args) { System out println( quit 退出 ); System out println( task A 啟動任務A 時長為 秒 ); System out println( size 設置當前線程池大小為 ); System out println( max 設置線程池最大線程數為 ); System out println();
final ThreadPool pool = new ThreadPool( ); pool init();
Thread cmdThread = new Thread() { public void run() {
BufferedReader reader = new BufferedReader(new InputStreamReader(System in));
while(true) { try { String line = reader readLine(); String words[] = line split( ); if(words[ ] equalsIgnoreCase( quit )) { System exit( ); }else if(words[ ] equalsIgnoreCase( size ) && words length >= ) { try { int size = Integer parseInt(words[ ]); pool setPoolSize(size); }catch(Exception e) {
}
}else if(words[ ] equalsIgnoreCase( max ) && words length >= ) { try { int max = Integer parseInt(words[ ]); pool setMaxPoolSize(max); }catch(Exception e) {
}
}else if(words[ ] equalsIgnoreCase( task ) && words length >= ) { try { int timelen = Integer parseInt(words[ ]); SimpleTask task = new SimpleTask(words[ ] timelen * ); pool processTask(task); }catch(Exception e) {
}
}
} catch (IOException e) { e printStackTrace();
}
}
}
};
cmdThread start();
/**//*
for(int i= ; i< ; i++){
SimpleTask task = new SimpleTask( Task + i (i+ )* ); pool processTask(task);
}*/
}
}
class SimpleTask implements ThreadTask {
private String taskName;
private int timeLen;
public SimpleTask(String taskName int timeLen) { this taskName = taskName; this timeLen = timeLen;
}
public void run() { System out println(Thread currentThread() getId() +
: START TASK + taskName + );
try { Thread sleep(timeLen); } catch (InterruptedException e) {
}
System out println(Thread currentThread() getId() +
: END TASK + taskName + );
}
}
使用此線程池相當簡單 下面兩行代碼初始化線程池
ThreadPool pool = new ThreadPool( ); pool init();
要處理的任務實現ThreadTask 介面即可(如測試代碼里的SimpleTask) 這個介面只有一個方法run()
兩行代碼即可調用
lishixin/Article/program/Java/hx/201311/27203
② 什麼是java線程池
找的資料,你看一下吧:x0dx0a多線程技術主要解決處理器單元內多個線程執行的問題,褲嘩它可以顯著減讓汪少處理器單元的閑置時間,增加處理器單元的吞吐能力。x0dx0a x0dx0a 假設一個伺服器完成一項任務所需時間為:T1 創建線程時間,T2 在線程中執行任務的時間,T3 銷毀線程時間。x0dx0a x0dx0a 如果:T1 + T3 遠大於 T2,則可以採用線程池,以提高坦純仔伺服器性能。x0dx0a 一個線程池包括以下四個基本組成部分:x0dx0a 1、線程池管理器(ThreadPool):用於創建並管理線程池,包括 創建線程池,銷毀線程池,添加新任務;x0dx0a 2、工作線程(PoolWorker):線程池中線程,在沒有任務時處於等待狀態,可以循環的執行任務;x0dx0a 3、任務介面(Task):每個任務必須實現的介面,以供工作線程調度任務的執行,它主要規定了任務的入口,任務執行完後的收尾工作,任務的執行狀態等;x0dx0a 4、任務隊列(taskQueue):用於存放沒有處理的任務。提供一種緩沖機制。x0dx0a x0dx0a 線程池技術正是關注如何縮短或調整T1,T3時間的技術,從而提高伺服器程序性能的。它把T1,T3分別安排在伺服器程序的啟動和結束的時間段或者一些空閑的時間段,這樣在伺服器程序處理客戶請求時,不會有T1,T3的開銷了。x0dx0ax0dx0a 線程池不僅調整T1,T3產生的時間段,而且它還顯著減少了創建線程的數目,看一個例子:x0dx0ax0dx0a 假設一個伺服器一天要處理50000個請求,並且每個請求需要一個單獨的線程完成。在線程池中,線程數一般是固定的,所以產生線程總數不會超過線程池中線程的數目,而如果伺服器不利用線程池來處理這些請求則線程總數為50000。一般線程池大小是遠小於50000。所以利用線程池的伺服器程序不會為了創建50000而在處理請求時浪費時間,從而提高效率。
③ 讓ThreadPoolExecutor無所遁形:Java線程池運行原理詳解
深入探討ThreadPoolExecutor的核心工作原理,我們了解到這個Java類在並發和多線程討論中不可或缺。它管理線程池內的線程,包括創建、執行、管理及監控。理解其如何確保線程池正確運作至關重要。以下解析ThreadPoolExecutor的關鍵元素:
線程池狀態和控制流程概述:ThreadPoolExecutor維護一個ctl的原子整型變數,其高位存儲線程池狀態,低位存儲線程數量,通過內部狀態控制管理線程池。
ctl的位欄位表示方法:定義為高位存儲狀態,低位存儲線程數量,確保線程池狀態准確反映生命周期。
狀態轉換及控制:通過ctl變數控制,提供輔助函數管理狀態,如獲取狀態和線程數量,確保線程池運行流程協調。
ThreadPoolExecutor的屬性詳解:包括核心線程數、最大線程數、任務隊列、keepAliveTime、ThreadFactory及拒絕策略等,共同決定線程池行為與性能。
execute方法的任務提交流程:接收任務,根據線程數量和核心線程數比較決定是否添加新工作線程,成功加入隊列後檢查狀態,嘗試添加非核心線程,失敗調用拒絕策略。
submit方法與FutureTask的協同:提交帶返回值的任務轉化為FutureTask,調用execute方法執行,返回Future對象獲取非同步執行結果。
shutdown和shutdownNow方法的區別:shutdown平緩關閉線程池,等待正在執行任務,不接收新任務;shutdownNow則激進停止所有執行任務,並返回等待執行的任務列表。
ThreadPoolExecutor的關鍵內部類:Worker類封裝線程池中的每個工作線程,實現Runnable介面;內部阻塞隊列實現線程安全管理任務。
Worker類的作用和生命周期:使用ThreadFactory創建線程,控制線程狀態,執行任務隊列中的任務,直到線程池終止或無任務執行。
內部阻塞隊列的實現與特性:使用線程安全的隊列暫存待執行任務,支持不同類型的阻塞隊列,如LinkedBlockingQueue、ArrayBlockingQueue、PriorityBlockingQueue,各有特殊使用場景和性能特點。
延遲任務處理:配置為ScheledThreadPoolExecutor時使用DelayedWorkQueue處理定時任務。
ThreadPoolExecutor的擴展與自定義:提供覆寫的鉤子方法,實現自定義擴展和自定義拒絕策略。
拓展方法的應用:覆寫beforeExecute、afterExecute和terminated方法實現自定義邏輯,如記錄日誌、計算任務執行時間、收集線程池統計信息等。
自定義拒絕策略的應用:實現RejectedExecutionHandler介面創建自定義拒絕策略,如記錄日誌、嘗試重新提交任務。
實戰案例:通過創建監控線程池運行狀態的ThreadPoolExecutor並實施自定義擴展,實現對線程池的高效管理。
④ Java多線程和單線程怎麼通俗易懂的理解
1. 深入理解Java多線程與單線程:如同工廠流水線的生動比喻
想像一下,一個工廠生產過程可以被看作是單線程,就像只有一個員工在獨立完成各項任務。
在Java的世界裡,多線程就像擁有多個員工,他們可以同時並行地完成各自的工作,共享資源但擁有獨立的工作流程。
這就是Java對多線程和單線程的直觀解釋。
2. Java的核心特性之一就是支持多線程,線程是程序執行的基本單元,每個線程都有自己的棧空間,雖然可以共享程序的全局資源,但每個線程的執行是獨立的。
3. 要實現多線程,你可以選擇繼承Thread類或者實現Runnable介面。
前者適用於簡單擴展,而後者則避免了Java單繼承的限制,但設計上稍顯復雜。
4. 創建Java線程有三種方法:
繼承Thread類:創建一個子類,重寫run()方法,然後實例化Thread並調用start()。
實現Runnable介面:創建Runnable實現類,重寫run()方法,通過Thread的構造方法將Runnable對象傳遞。
使用Callable和FutureTask:Callable介面提供了有返回值和異常處理的能力,通過FutureTask包裝Callable並啟動線程,get()方法用於獲取結果。
5. 線程的生命周期分為五個階段:新建、就緒、運行、阻塞和死亡。
每個階段都對應著線程在工廠流水線上的不同狀態。
6. 調度機制在單CPU和多CPU環境下有所不同,Java採用分時或搶占式模型,優先順序高的線程優先獲取CPU資源。
7. 線程間的協作和同步至關重要,如通過join()方法實現線程同步,讓主線程等待子線程完成。
8. 後台線程則默默地為其他任務服務,守護線程的生命周期與主線程緊密相連。
9. 同步代碼塊和鎖機制(如synchronized關鍵字)確保在並發環境下數據的一致性,避免諸如窗口賣票問題中的並發沖突。
10. 線程池作為高級工具,通過Executors類簡化了線程管理,提高了性能。
線程池可設置固定大小,控制並發量,確保資源的合理分配。
11. 此外,ThreadGroup和線程通信方法(如Object類提供的wait(), notify()等)在處理線程組和線程間的協作中起到關鍵作用。
總的來說,Java的多線程和單線程就像工廠中的不同工作模式,既獨立又協作,為程序並發執行提供了強大的支持。
通過理解這些概念,開發者可以更好地設計和優化他們的並發程序,提升效率,保證數據一致性。
⑤ Java面試之線程池參數設置
在Java中,提供多種線程池類型,以滿足不同任務需求。常用類型包括:
緩存線程池(Executors.newCachedThreadPool):動態創建線程,根據任務數量調整大小。
定時線程池(Executors.newScheledThreadPool):按固定時間間隔或延遲執行任務。
固定線程池(Executors.newFixedThreadPool):維護固定數量線程,任務入隊等待。
單線程線程池(Executors.newSingleThreadExecutor):包含一個線程,任務順序執行。
工作竊取線程池(Executors.newWorkStealingPool):內部使用ForkJoinPool,適用於多線程並行操作。
這些線程池都是通過Executors類創建的,但推薦使用ThreadPoolExecutor自定義參數。關鍵參數包括:
核心線程數量(corePoolSize):線程池中保持的最少線程數。
最大線程數量(maximumPoolSize):線程池能容納的最大線程數。
存活時間(keepAliveTime):線程閑置時間超過此值將被銷毀。
存活時間單位(TimeUnit):keepAliveTime的時間單位。
阻塞隊列(workQueue):保存待執行任務。
線程創建工廠(ThreadFactory):自定義線程屬性。
飽和策略(RejectedExecutionHandler):隊列滿時,決定如何處理新任務。
配置參數時,考慮任務類型、CPU核數等,有經驗值、最佳線程數演算法等方法。經驗值法考慮任務密集度,IO密集型設置為2N,CPU密集型設置為N+1;最佳線程數演算法則綜合任務等待與執行時間。Java並發編程實踐與Java虛擬機提供不同計算方法,旨在優化線程池性能。
實際應用中,需綜合分析任務特性、系統負載等,通過實驗與調整找到平衡點。監測工具與基準負載測試有助於確定線程池最優大小,實現資源高效利用。