package threadpool_test; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.TimeUnit; /** * 自定義一個簡單的線程池 * * ***/ public class ThreadPool { private static final int coreThreadNum=3;//核心線程數 private static final int maxThreadNum=8;//最大線程數 private boolean working=true;//打開、關閉線程池 private BlockingQueue<Thread> workThreads=new LinkedBlockingDeque<>(maxThreadNum);//當前工作線程 private BlockingQueue<Runnable> tasks=new LinkedBlockingDeque<>(10);//任務隊列 public void execute(Runnable task) throws InterruptedException{ if(task==null) throw new NullPointerException(); int workNum=workThreads.size(); if(workNum<coreThreadNum ){//當前工作線程少於核心線程數,立即啟動一個線程進行工作 Worker worker=new Worker(task); Thread thread=new Thread(worker); workThreads.offer(thread);//特殊值,add會拋出異常 thread.start(); } else if(tasks.size()<10){//任務池還沒滿,就把任務放進任務池里 tasks.offer(task); } else if(workNum<maxThreadNum && tasks.size()==10){//任務隊列滿,開啟多余線程來完成任務 Worker worker=new Worker(); Thread thread=new Thread(worker); System.out.println("開啟新線程了"+thread.getName()); workThreads.offer(thread); thread.start(); } else{ System.out.println("放棄該任務"); return; } } public void shutDown(){ this.working=false; for(Thread worker:workThreads){ System.out.println("終止線程名:"+worker.getName()); worker.interrupt(); } System.out.println("終止線程池線程"); Thread.currentThread().interrupt(); } private class Worker implements Runnable{//任務包裝類 private Runnable task_origal; public Worker() { } public Worker(Runnable task) { this.task_origal=task; } @Override public void run() { if(task_origal!=null) task_origal.run(); while(working){ try { Runnable task=tasks.take();//阻塞提取任務,阻塞狀態下的中斷並不會真的中斷 task.run(); } catch (InterruptedException e) { System.out.println("真的終止了"); Thread.currentThread().interrupt(); } } } } }
package threadpool_test; import java.util.concurrent.TimeUnit; /** * 測試類 * **/ public class testMain { public static void main(String[] args) throws InterruptedException { ThreadPool pool=new ThreadPool(); for(int i=0;i<20;i++){ pool.execute(new Task("任務"+i)); } TimeUnit.SECONDS.sleep(4); pool.shutDown(); } }
顯示結果:
當前運行線程名:Thread-0當前任務名為:任務0 當前運行線程名:Thread-2當前任務名為:任務2 當前運行線程名:Thread-2當前任務名為:任務4 當前運行線程名:Thread-2當前任務名為:任務5 當前運行線程名:Thread-2當前任務名為:任務6 當前運行線程名:Thread-2當前任務名為:任務7 當前運行線程名:Thread-2當前任務名為:任務8 當前運行線程名:Thread-2當前任務名為:任務9 當前運行線程名:Thread-2當前任務名為:任務10 當前運行線程名:Thread-2當前任務名為:任務11 當前運行線程名:Thread-2當前任務名為:任務12 開啟新線程了Thread-3 當前運行線程名:Thread-1當前任務名為:任務1 當前運行線程名:Thread-1當前任務名為:任務14 當前運行線程名:Thread-3當前任務名為:任務15 當前運行線程名:Thread-3當前任務名為:任務16 當前運行線程名:Thread-3當前任務名為:任務17 當前運行線程名:Thread-3當前任務名為:任務18 當前運行線程名:Thread-3當前任務名為:任務19 當前運行線程名:Thread-0當前任務名為:任務3 終止線程名:Thread-0 真的終止了 終止線程名:Thread-1 終止線程名:Thread-2 真的終止了 真的終止了 終止線程名:Thread-3 終止線程池線程 真的終止了
ps:該線程池功能非常之簡單,僅為了加深線程池核心原理而做。里面關於任務隊列滿后的處理情況,在這里直接簡單的使用放棄該任務的方法;