當前位置:首頁 » 操作系統 » 線程池源碼java

線程池源碼java

發布時間: 2024-06-07 00:19:32

java線程池怎麼實現的

線程池簡介:

多線程技術主要解決處理器單元內多個線程執行的問題,它可以顯著減少處理器單元的閑置時間,增加處理器單元的吞吐能力。


假設一個伺服器完成一項任務所需時間為:T1 創建線程時間,T2 在線程中執行任務的時間,T3 銷毀線程時間。

如果:T1 + T3 遠大於 T2,則可以採用線程池,以提高伺服器性能。

一個線程池包括以下四個基本組成部分:

1、線程池管理器(ThreadPool):用於創建並管理線程池,包括 創建線程池,銷毀線程池,添加新任務;

2、工作線程(PoolWorker):線程池中線程,在沒有任務時處於等待狀態,可以循環的執行任務;

3、任務介面(Task):每個任務必須實現的介面,以供工作線程調度任務的執行,它主要規定了任務的入口,任務執行完後的收尾工作,任務的執行狀態等;

4、任務隊列(taskQueue):用於存放沒有處理的任務。提供一種緩沖機制。

線程池技術正是關注如何縮短或調整T1,T3時間的技術,從而提高伺服器程序性能的。它把T1,T3分別安排在伺服器程序的啟動和結束的時間段或者一些空閑的時間段,這樣在伺服器程序處理客戶請求時,不會有T1,T3的開銷了。

線程池不僅調整T1,T3產生的時間段,而且它還顯著減少了創建線程的數目,看一個例子:

假設一個伺服器一天要處理50000個請求,並且每個請求需要一個單獨的線程完成。在線程池中,線程數一般是固定的,所以產生線程總數不會超過線程池中線程的數目,而如果伺服器不利用線程池來處理這些請求則線程總數為50000。一般線程池大小是遠小於50000。所以利用線程池的伺服器程序不會為了創建50000而在處理請求時浪費時間,從而提高效率。

代碼實現中並沒有實現任務介面,而是把Runnable對象加入到線程池管理器(ThreadPool),然後剩下的事情就由線程池管理器(ThreadPool)來完成了

packagemine.util.thread;

importjava.util.LinkedList;
importjava.util.List;

/**
*線程池類,線程管理器:創建線程,執行任務,銷毀線程,獲取線程基本信息
*/
publicfinalclassThreadPool{
//線程池中默認線程的個數為5
privatestaticintworker_num=5;
//工作線程
privateWorkThread[]workThrads;
//未處理的任務
_task=0;
//任務隊列,作為一個緩沖,List線程不安全
privateList<Runnable>taskQueue=newLinkedList<Runnable>();
;

//創建具有默認線程個數的線程池
privateThreadPool(){
this(5);
}

//創建線程池,worker_num為線程池中工作線程的個數
privateThreadPool(intworker_num){
ThreadPool.worker_num=worker_num;
workThrads=newWorkThread[worker_num];
for(inti=0;i<worker_num;i++){
workThrads[i]=newWorkThread();
workThrads[i].start();//開啟線程池中的線程
}
}

//單態模式,獲得一個默認線程個數的線程池
(){
returngetThreadPool(ThreadPool.worker_num);
}

//單態模式,獲得一個指定線程個數的線程池,worker_num(>0)為線程池中工作線程的個數
//worker_num<=0創建默認的工作線程個數
(intworker_num1){
if(worker_num1<=0)
worker_num1=ThreadPool.worker_num;
if(threadPool==null)
threadPool=newThreadPool(worker_num1);
returnthreadPool;
}

//執行任務,其實只是把任務加入任務隊列,什麼時候執行有線程池管理器覺定
publicvoidexecute(Runnabletask){
synchronized(taskQueue){
taskQueue.add(task);
taskQueue.notify();
}
}

//批量執行任務,其實只是把任務加入任務隊列,什麼時候執行有線程池管理器覺定
publicvoidexecute(Runnable[]task){
synchronized(taskQueue){
for(Runnablet:task)
taskQueue.add(t);
taskQueue.notify();
}
}

//批量執行任務,其實只是把任務加入任務隊列,什麼時候執行有線程池管理器覺定
publicvoidexecute(List<Runnable>task){
synchronized(taskQueue){
for(Runnablet:task)
taskQueue.add(t);
taskQueue.notify();
}
}

//銷毀線程池,該方法保證在所有任務都完成的情況下才銷毀所有線程,否則等待任務完成才銷毀
publicvoiddestroy(){
while(!taskQueue.isEmpty()){//如果還有任務沒執行完成,就先睡會吧
try{
Thread.sleep(10);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
//工作線程停止工作,且置為null
for(inti=0;i<worker_num;i++){
workThrads[i].stopWorker();
workThrads[i]=null;
}
threadPool=null;
taskQueue.clear();//清空任務隊列
}

//返回工作線程的個數
publicintgetWorkThreadNumber(){
returnworker_num;
}

//返回已完成任務的個數,這里的已完成是只出了任務隊列的任務個數,可能該任務並沒有實際執行完成
(){
returnfinished_task;
}

//返回任務隊列的長度,即還沒處理的任務個數
publicintgetWaitTasknumber(){
returntaskQueue.size();
}

//覆蓋toString方法,返回線程池信息:工作線程個數和已完成任務個數
@Override
publicStringtoString(){
return"WorkThreadnumber:"+worker_num+"finishedtasknumber:"
+finished_task+"waittasknumber:"+getWaitTasknumber();
}

/**
*內部類,工作線程
*/
{
//該工作線程是否有效,用於結束該工作線程
privatebooleanisRunning=true;

/*
*關鍵所在啊,如果任務隊列不空,則取出任務執行,若任務隊列空,則等待
*/
@Override
publicvoidrun(){
Runnabler=null;
while(isRunning){//注意,若線程無效則自然結束run方法,該線程就沒用了
synchronized(taskQueue){
while(isRunning&&taskQueue.isEmpty()){//隊列為空
try{
taskQueue.wait(20);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
if(!taskQueue.isEmpty())
r=taskQueue.remove(0);//取出任務
}
if(r!=null){
r.run();//執行任務
}
finished_task++;
r=null;
}
}

//停止工作,讓該線程自然執行完run方法,自然結束
publicvoidstopWorker(){
isRunning=false;
}
}
}

② java常用的幾種線程池實例講解

下面給你介紹4種線程池:

1、newCachedThreadPool:

  • 底層:返回ThreadPoolExecutor實例,corePoolSize為0;maximumPoolSize為Integer.MAX_VALUE;keepAliveTime為60L;unit為TimeUnit.SECONDS;workQueue為SynchronousQueue(同步隊列)

  • 通俗:當有新任務到來,則插入到SynchronousQueue中,由於SynchronousQueue是同步隊列,因此會在池中尋找可用線程來執行,若有可以線程則執行,若沒有可用線程則創建一個線程來執行該任務;若池中線程空閑時間超過指定大小,則該線程會被銷毀。

  • 適用:執行很多短期非同步的小程序或者負載較輕的伺服器

2、newFixedThreadPool:


  • 底層:返回ThreadPoolExecutor實例,接收參數為所設定線程數量nThread,corePoolSize為nThread,maximumPoolSize為nThread;keepAliveTime為0L(不限時);unit為:TimeUnit.MILLISECONDS;WorkQueue為:new LinkedBlockingQueue<Runnable>()無解阻塞隊列

  • 通俗:創建可容納固定數量線程的池子,每隔線程的存活時間是無限的,當池子滿了就不在添加線程了;如果池中的所有線程均在繁忙狀態,對於新任務會進入阻塞隊列中(無界的阻塞隊列)

  • 適用:執行長期的任務,性能好很多

3、newSingleThreadExecutor

  • 底層:包裝的ThreadPoolExecutor實例,corePoolSize為1;maximumPoolSize為1;keepAliveTime為0L;unit為:TimeUnit.MILLISECONDS;workQueue為:new LinkedBlockingQueue<Runnable>()無解阻塞隊列

  • 通俗:創建只有一個線程的線程池,且線程的存活時間是無限的;當該線程正繁忙時,對於新任務會進入阻塞隊列中(無界的阻塞隊列)

  • 適用:一個任務一個任務執行的場景

4、NewScheledThreadPool:

  • 底層:創建ScheledThreadPoolExecutor實例,corePoolSize為傳遞來的參數,maximumPoolSize為Integer.MAX_VALUE;keepAliveTime為0;unit為:TimeUnit.NANOSECONDS;workQueue為:new DelayedWorkQueue()一個按超時時間升序排序的隊列

  • 通俗:創建一個固定大小的線程池,線程池內線程存活時間無限制,線程池可以支持定時及周期性任務執行,如果所有線程均處於繁忙狀態,對於新任務會進入DelayedWorkQueue隊列中,這是一種按照超時時間排序的隊列結構

  • 適用:周期性執行任務的場景

最後給你說一下線程池任務執行流程:

  • 當線程池小於corePoolSize時,新提交任務將創建一個新線程執行任務,即使此時線程池中存在空閑線程。

  • 當線程池達到corePoolSize時,新提交任務將被放入workQueue中,等待線程池中任務調度執行

  • 當workQueue已滿,且maximumPoolSize>corePoolSize時,新提交任務會創建新線程執行任務

  • 當提交任務數超過maximumPoolSize時,新提交任務由RejectedExecutionHandler處理

  • 當線程池中超過corePoolSize線程,空閑時間達到keepAliveTime時,關閉空閑線程

  • 當設置allowCoreThreadTimeOut(true)時,線程池中corePoolSize線程空閑時間達到keepAliveTime也將關閉

③ java線程池(一) 簡述線程池的幾種使用方式

首先說明下java線程是如何實現線程重用的
1. 線程執行完一個Runnable的run()方法後,不會被殺死
2. 當線程被重用時,這個線程會進入新Runnable對象的run()方法12

java線程池由Executors提供的幾種靜態方法創建線程池。下面通過代碼片段簡單介紹下線程池的幾種實現方式。後續會針對每個實現方式做詳細的說明
newFixedThreadPool
創建一個固定大小的線程池
添加的任務達到線程池的容量之後開始加入任務隊列開始線程重用總共開啟線程個數跟指定容量相同。
@Test
public void newFixedThreadPool() throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService = Executors.newFixedThreadPool(1, new ThreadFactoryBuilder().build());
RunThread run1 = new RunThread("run 1");
executorService.execute(run1);
executorService.shutdown();
}12345678

newSingleThreadExecutor
僅支持單線程順序處理任務
@Test
public void newSingleThreadExecutor() throws Exception {
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().build());
executorService.execute(new RunThread("run 1"));
executorService.execute(new RunThread("run 2"));
executorService.shutdown();

}123456789

newCachedThreadPool
這種情況跟第一種的方式類似,不同的是這種情況線程池容量上線是Integer.MAX_VALUE 並且線程池開啟緩存60s
@Test
public void newCachedThreadPool() throws Exception {
ExecutorService executorService = Executors.newCachedThreadPool();
executorService = Executors.newCachedThreadPool(new ThreadFactoryBuilder().build());
executorService.execute(new RunThread("run 1"));
executorService.execute(new RunThread("run 2"));
executorService.shutdown();

}123456789

newWorkStealingPool
支持給定的並行級別,並且可以使用多個隊列來減少爭用。
@Test
public void newWorkStealingPool() throws Exception {
ExecutorService executorService = Executors.newWorkStealingPool();
executorService = Executors.newWorkStealingPool(1);
RunThread run1 = new RunThread("run 1");
executorService.execute(run1);
executorService.shutdown();

}123456789

newScheledThreadPool
看到的現象和第一種相同,也是在線程池滿之前是新建線程,然後開始進入任務隊列,進行線程重用
支持定時周期執行任務(還沒有看完)
@Test
public void newScheledThreadPool() throws Exception {
ExecutorService executorService = Executors.newScheledThreadPool(1);
executorService = Executors.newScheledThreadPool(1, new ThreadFactoryBuilder().build());
executorService.execute(new RunThread("run 1"));
executorService.execute(new RunThread("run 2"));
executorService.shutdown();

}

④ Java線程池優化for循環

那麼我們要做的就是把要做的事情開多線程里去處理,可以簡單的實現如下

packagecom.wenxy.test...bank;

importjava.util.Iterator;
importjava.util.concurrent.Executor;
importjava.util.concurrent.Executors;

publicclassTestLoop{

publicstaticinti=0;

voiddoSomething(){
System.out.println(Thread.currentThread().getName()
+"isdoing。。。andi="+i);
i++;
}

publicstaticvoidmain(String[]args){

陪孝finalTestLooptestLoop=newTestLoop();

//創建一個線程池,用10個線程處理
Executorexecutor=Executors.newFixedThreadPool(10);

胡滾for(inti=0;i<100;i++){
executor.execute(newRunnable(){

@Override
publicvoidrun(){
蘆做稿testLoop.doSomething();
}
});
}

}

}

⑤ 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 定義一個線程池 循環遍歷list,進行讀寫操作

importjava.util.List;
importjava.util.concurrent.Callable;
importjava.util.concurrent.ExecutionException;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;
importjava.util.concurrent.Future;

/**
*並發處理器
*適用於如下場景(舉例):
*一個任務隊列,有150個任務需要並發處理,使用此對象,可以每次並發執行20次(可設置),則總共串列執行8次並發,可獲取執行結果
*
*@param<T>類型T限制為任務Callable使用的數據對象和返回結果的數據對象為同一個bean
*/
publicclassConcurrentExcutor<T>
{
/**非空,所有任務數組*/
privateCallable<T>[]tasks;

/**非空,每次並發需要處理的任務數*/
privateintnumb;

/**可選,存放返回結果,這里有個限制,泛型T必須為Callable返回的類型T*/
privateList<T>result;

/**
*無參構造
*/
publicConcurrentExcutor()
{
super();
}

/**
*不需要返回結果的任務用此創建對象
*@paramtasks
*@paramnumb
*/
publicConcurrentExcutor(Callable<T>[]tasks,intnumb)
{
super();
this.tasks=tasks;
this.numb=numb;
}

/**
*需要結果集用此方法創建對象
*@paramtasks
*@paramnumb
*@paramresult
*/
publicConcurrentExcutor(Callable<T>[]tasks,intnumb,List<T>result)
{
super();
this.tasks=tasks;
this.numb=numb;
this.result=result;
}

publicvoidexcute()
{
//參數校驗
if(tasks==null||numb<1)
{
return;
}

//待處理的任務數
intnum=tasks.length;
if(num==0)
{
return;
}

//第一層循環,每numb條數據作為一次並發
for(inti=0;i<(int)Math.floor(num/numb)+1;i++)
{
//用於記錄此次numb條任務的處理結果
Future[]futureArray;
if(numb>num)
{
futureArray=newFuture[num];
}
else
{
futureArray=newFuture[numb];
}

//創建線程容器
ExecutorServicees=Executors.newCachedThreadPool();

//第二層循環,針對這numb條數據進行處理
for(intj=i*numb;j<(i+1)*numb;j++)
{
//如果超出數組長度,退出循環
if(j+1>num)
{
break;
}
//執行任務,並設置Future到數組中
futureArray[j%numb]=es.submit(tasks[j]);
}

//將結果放入result中
if(result!=null)
{
for(intj=0;j<futureArray.length;j++)
{
try
{
if(futureArray[j]!=null)
{
Objecto=futureArray[j].get();
result.add((T)o);
}
}
catch(InterruptedExceptione)
{
System.out.println("處理Future時發生InterruptedException異常,目標Future為:"+futureArray[j].toString());
e.printStackTrace();
}
catch(ExecutionExceptione)
{
System.out.println("處理Future時發生ExecutionException異常,目標Future為:"+futureArray[j].toString());
e.printStackTrace();
}
}
}

es.shutdown();
}
}

⑦ 什麼是java線程池

多線程是為了能夠讓計算機資源合理的分配,對於處理不同的任務創建不同的線程進行處理,但是計算機創建一個線程或者銷毀一個線程所花費的也是比較昂貴的,有時候需要同時處理的事情比較多,就需要我們頻繁的進行線程的創建和銷毀,這樣花費的時間也是比較多的。為了解決這一問題,我們就可以引用線程池的概念。
所謂線程池就是將線程集中管理起來,當需要線程的時候,可以從線程池中獲取空閑的線程,這樣可以減少線程的頻繁創建與銷毀,節省很大的時間和減少很多不必要的操作。
在java中提供了ThreadPoolExecutor類來進行線程的管理,這個類繼承於AbstractExecutorService,而AbstractExecutorService實現了ExecutorService介面,我們可以使用ThreadPoolExecutor來進行線程池的創建。
在ThreadPoolExecutor的構造方法中,有多個參數,可以配置不同的參數來進行優化。這個類的源碼構造方法為:
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)其中每個參數代表的意義分別為
corePoolSize : 線程池中的核心線程數量,當線程池中當前的線程數小於這個配置的時候,如果有一個新的任務到來,即使線程池中還存在空閑狀態的線程,程序也會繼續創建一個新的線程放進線程池當中
maximumPoolSize: 線程池中的線程最大數量
keepAliveTime:當線程池中的線程數量大於配置的核心線程數量(corePoolSize)的時候,如果當前有空閑的線程,則當這個空閑線程可以存在的時間,如果在keepAliveTime這個時間點內沒有新的任務使用這個線程,那麼這個線程將會結束,核心線程不會結束,但是如果配置了allowCoreThreadTimeOut = true,則當空閑時間超過keepAliveTime之後,線程也會被結束調,默認allowCoreThreadTimeOut = false,即表示默認情況下,核心線程會一直存在於線程池當中。
unit : 空閑線程保持連接時間(keepAliveTime)的時間單位
workQueue:阻塞的任務隊列,用來保存等待需要執行的任務。
threadFactory :線程工廠,可以根據自己的需求去創建線程的對象,設置線程的名稱,優先順序等屬性信息。
handler:當線程池中存在的線程數超過設置的最大值之後,新的任務就會被拒絕,可以自己定義一個拒絕的策略,當新任務被拒絕之後,就會使用hander方法進行處理。
在java中也提供了Executors工具類,在這個工具類中提供了多個創建線程池的靜態方法,其中包含newCachedThreadPool、newFixedThreadPool、newScheledThreadPool、newSingleThreadExecutor等。但是他們每個方法都是創建了ThreadPoolExecutor對象,不同的是,每個對象的初始 參數值不一樣;

熱點內容
linux修改遠程埠 發布:2024-11-26 22:35:53 瀏覽:981
卡通農場伺服器怎麼連不上 發布:2024-11-26 22:26:54 瀏覽:194
馬嘉祺密碼1的答案是什麼 發布:2024-11-26 22:19:16 瀏覽:954
linux常用命令vi 發布:2024-11-26 22:17:40 瀏覽:4
sqlserver教材 發布:2024-11-26 22:07:21 瀏覽:632
安卓p圖工具哪個好 發布:2024-11-26 22:02:25 瀏覽:320
稅控盤密碼在哪裡改 發布:2024-11-26 21:55:54 瀏覽:611
美版安卓系統為什麼連不了網 發布:2024-11-26 21:51:36 瀏覽:613
用公司伺服器搭建網站 發布:2024-11-26 21:42:00 瀏覽:357
忘記密碼魅族手機如何清除數據 發布:2024-11-26 21:34:17 瀏覽:156