手寫簡易線程池完整代碼

package com.thread.threadpool;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * 線程池
 */
public class ThreadPool extends Thread{

    //線程的數量
    private int size;

    //任務對列的大小
    private final int taskQueueSize;

    //默認任務對列的大小
    private final static int TASK_QUEUE_SIZE = 2000;

    //線程從 0 開始起命名
    private static volatile int seq = 0;

    //給線程的名字加前綴
    private final static String THREAD_PREFIX = "SIMPLE_THREAD_POOL-";

    //定義線程組
    private final static ThreadGroup GROUP = new ThreadGroup("POOL_GROUP");

    //任務隊列
    private final static LinkedList<Runnable> TASK_QUEUE = new LinkedList<>();

    //存放線程的集合
    private final static List<WorkerTask> THREAD_QUEUE = new ArrayList<>();

    //定一默認的拒絕策略
    private final  DiscardPolicy discardPolicy;

    //線程池的狀態
    private volatile boolean destroy = false;

    //默認拒絕策略
    public final static DiscardPolicy DEFAULT_DISCARD_POLICY = ()->{
        throw new DiscardException("over ......");
    };

    //最小線程數
    private int min;

    //最小線程數默認值
    private final static int MIN_VALUE = 4;

    //活躍線程數
    private int active;

    //活躍線程數默認值
    private final static int ACTIVE_VALUE = 8;

    //最大線程數
    private int max;

    //最大線程數默認值
    private final static int MAX_VALUE = 12;

    public ThreadPool(){
        this.min = MIN_VALUE;
        this.active = ACTIVE_VALUE;
        this.max = MAX_VALUE;
        this.taskQueueSize = TASK_QUEUE_SIZE;
        this.discardPolicy = DEFAULT_DISCARD_POLICY;
        init();
    }

    public ThreadPool(int min,int active,int max,int taskQueueSize,DiscardPolicy discardPolicy){
        this.min = min;
        this.active = active;
        this.max = max;
        this.taskQueueSize = taskQueueSize;
        this.discardPolicy = discardPolicy;
        init();
    }

    //重寫線程池run()方法
    @Override
    public void run(){
        while (!destroy){
            System.out.printf("pool#Min:%d,active:%d,max:%d,ThreadQueueSize:%d,TaskQueueSize:%d\n",
                    min,active,max,THREAD_QUEUE.size(),TASK_QUEUE.size());
            try {
                Thread.sleep(5_000);
                if (TASK_QUEUE.size()>active && size<active){
                    for (int i = size ; i <active ; i++) {
                        creatWorkTask();
                    }
                    //給線程池數量賦值
                    this.size = active;
                    System.out.println("擴容到 active");
                }else if (TASK_QUEUE.size()>max && size<max){
                    for (int i = active ; i <max ; i++) {
                        creatWorkTask();
                    }
                    //給線程池數量賦值
                    this.size = max;
                    System.out.println("擴容到 max");
                }

                if (TASK_QUEUE.isEmpty() && size>active){
                    synchronized (THREAD_QUEUE){
                        System.out.println("開始 release thread");
                        int releaseSize = size - active;
                        Iterator<WorkerTask> iterator = THREAD_QUEUE.iterator();
                        while (iterator.hasNext()){
                            if (releaseSize<=0){
                                break;
                            }
                            WorkerTask workerTask = iterator.next();
                            if (workerTask.getTaskStatus()==TaskStatus.BLOCKED){
                                //先關閉再打斷
                                workerTask.colse();
                                workerTask.interrupt();
                                iterator.remove();
                                releaseSize--;
                            }
                        }
                        size = active;
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public int getSize() {
        return size;
    }

    public int getMin() {
        return min;
    }

    public int getActive() {
        return active;
    }

    public int getMax() {
        return max;
    }

    public int getTaskQueueSize() {
        return taskQueueSize;
    }

    //查看線程池是否可用
    public boolean isDestroy(){
        return this.destroy;
    }

    //初始化線程池
    private void init() {
        for (int i = 0; i <min ; i++) {
            creatWorkTask();
        }
        //給線程池數量賦值
        this.size = min;

        //開啓線程池線程
        this.start();
    }

    //添加任務
    public void submit(Runnable runnable){

        //如果線程池已經被破壞,不能提交任務
        if (isDestroy()){
            //非法狀態異常
            throw new IllegalStateException("the thread pool is already destoryed and cant submit!!");
        }

        //這裏是添加任務,下面有消耗任務,但是,你需要等我添加完成之後,你才能消耗,所以得枷鎖
        synchronized (TASK_QUEUE){
            if (TASK_QUEUE.size()>taskQueueSize){
                discardPolicy.discar();
            }
            TASK_QUEUE.addLast(runnable);
            TASK_QUEUE.notifyAll();
        }
    }

    //創建線程
    private void creatWorkTask(){
        WorkerTask workerTask = new WorkerTask(GROUP,THREAD_PREFIX+(seq++));
        workerTask.start();
        //加入到集合中
        THREAD_QUEUE.add(workerTask);
    }

    //結束線程池
    public void shotdown() throws InterruptedException{
        while (!TASK_QUEUE.isEmpty()){
            Thread.sleep(50);
        }
        synchronized (THREAD_QUEUE){
            int initVal = THREAD_QUEUE.size();
            while (initVal>0){
                for (WorkerTask workerTask:THREAD_QUEUE){
                    if (workerTask.getTaskStatus()==TaskStatus.BLOCKED){
                        workerTask.interrupt();
                        workerTask.colse();
                        initVal--;
                    }else {
                        Thread.sleep(10);
                    }
                }
            }
            this.destroy = true;
            System.out.println("the thread pool is disposed");
        }

    }

    //用枚舉類型定義線程的狀態
    private enum TaskStatus{
        FREE,RUNNING,BLOCKED,DEAD
    }

    //定義運行時異常
    public static class DiscardException extends RuntimeException{
        public DiscardException(String message){
            super(message);
        }
    }

    //定義拒絕策略的接口
    public interface DiscardPolicy{
        //jdk1.8開始,接口內的所有方法,默認都是public類型
        void discar() throws DiscardException;
    }

    private static class WorkerTask extends Thread{
        //默認狀態爲free
        private volatile TaskStatus taskStatus = TaskStatus.FREE;

        //使用父親的構造器方法
        public WorkerTask(ThreadGroup group,String name){
            super(group,name);
        }

        public TaskStatus getTaskStatus() {
            return taskStatus;
        }

        //重寫run方法,避免線程執行完就被銷燬
        @Override
        public void run(){
            OUTER:
            while (taskStatus!=TaskStatus.DEAD){
                Runnable runnable;
                synchronized (TASK_QUEUE){
                    while (TASK_QUEUE.isEmpty()){
                        try {
                            taskStatus = TaskStatus.BLOCKED;
                            TASK_QUEUE.wait();
                        } catch (InterruptedException e) {
                            System.out.println("close!!");
                           break OUTER;
                        }
                    }

                    runnable = TASK_QUEUE.removeFirst();
                    //如果把執行的任務放在同步代碼塊裏,執行任務的時候,這個線程,還持有鎖,導致任務無法添加
//                    if (runnable!=null){
//                        taskStatus = TaskStatus.RUNNING;
//                        runnable.run();
//                        taskStatus = TaskStatus.FREE;
                    }
                if (runnable!=null){
                    taskStatus = TaskStatus.RUNNING;
                    runnable.run();
                    taskStatus = TaskStatus.FREE;
                }

            }
        }

        public void colse(){
            taskStatus = TaskStatus.DEAD;
        }
    }

    //測試一把
    public static void main(String[] args) {
        ThreadPool threadPool = new ThreadPool();
        for (int i = 0; i <40 ; i++) {
            threadPool.submit(()->{
                System.out.println(Thread.currentThread().getName()+"start");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"結束");
            });
        }
        try {
            Thread.sleep(50_000);
            threadPool.shotdown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }


}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章