手寫實現線程池,思路與ExecutorService一致

主要定義一個線程池應該具備的基本操作和方法
public interface ThreadPool {

    /**
     * 提交任務到線程池
     *
     * @param runnable
     */
    void execute(Runnable runnable);

    /**
     * 關閉線程池
     */
    void shutdown();

    /**
     * 初始化大小
     */
    int getInitSize();

    /**
     * 獲取線程池最大線程數
     *
     * @return
     */
    int getMaxsize();

    /**
     * 獲取線程池最大的線程數
     *
     * @return
     */
    int getCoreSize();

    /**
     * 獲取線程池中用於緩存任務隊列的大小
     *
     * @return
     */
    int getQuenSize();

    /**
     * 獲取線程池中活躍線程的數量
     *
     * @return
     */
    int getActiveCount();

    /**
     * 查詢線程池是否已經關閉
     *
     * @return
     */
    boolean isShutdown();


}
主要存放用於提交的Runnable,並且有limit限制
public interface RunnableQueue {

    /**
     * 當有新的任務進來時,放到隊列的末尾
     *
     * @param offer
     */
    void offer(Runnable offer);

    /**
     * 工作線程通過task獲取任務
     *
     * @return
     */
    Runnable task();

    /**
     * 獲取線程池緩存任務的數量
     *
     * @return
     */
    int size();
}
 當RunnableQueue超出範圍時,使用拒絕策略
@FunctionalInterface
public interface DenyPolicy {


    void reject(Runnable runnable, ThreadPool threadPool);

    /**
     * 直接丟棄任務
     */
    class DiscardDenyPolicy implements DenyPolicy {

        @Override
        public void reject(Runnable runnable, ThreadPool threadPool) {
            //TODO
        }
    }

    /**
     * 該拒絕策略會向任務提交者拋出異常
     */
    class AbortDenyPolicy implements DenyPolicy {

        @Override
        public void reject(Runnable runnable, ThreadPool threadPool) {
            throw new RunnableDenyPolicyException("");
        }
    }

    //該拒絕策略會使任務在提交者所在的線程執行
    class RunnerDenyPolicy implements DenyPolicy {

        @Override
        public void reject(Runnable runnable, ThreadPool threadPool) {
            if (!threadPool.isShutdown()) {
                runnable.run();
            }
        }
    }


}
public class RunnableDenyPolicyException extends RuntimeException {
    public RunnableDenyPolicyException(String message) {
        super(message);
    }
}
 主要用於線程池內部,不斷從queue中取出某個runnable,並運行run方法
public class InternalTask implements Runnable {

    /**
     * 任務隊列
     */
    private final RunnableQueue runnableQueue;

    /**
     * 標記
     */
    private volatile boolean running = true;

    public InternalTask(RunnableQueue runnableQueue) {
        this.runnableQueue = runnableQueue;
    }


    @Override
    public void run() {

        //當前任務爲running並且沒有被中斷,則不從隊列獲取下一個任務,
        while (running && !Thread.currentThread().isInterrupted()) {
            try {
                //獲取任務
                Runnable task = runnableQueue.task();
                task.run();
            } catch (Exception e) {
                running = false;
                break;
            }
        }
    }

    //停止當前任務
    public void stop() {
        this.running = false;
    }
}

public class LinkendRunnableQueue implements RunnableQueue {

    /**
     * 隊列最大長度
     */
    private final int limit;
    /**
     * 拒絕策略
     */
    private final DenyPolicy denyPolicy;
    /**
     * 存放任務
     */
    private final LinkedList<Runnable> runnableList = new LinkedList<>();

    /**
     * 線程池
     */
    private final ThreadPool threadPool;

    public LinkendRunnableQueue(int limit, DenyPolicy denyPolicy, ThreadPool threadPool) {
        this.limit = limit;
        this.denyPolicy = denyPolicy;
        this.threadPool = threadPool;
    }

    @Override
    public void offer(Runnable runnable) {
        synchronized (runnableList) {
            if (runnableList.size() >= limit) {
                //超過限制,啓動拒絕策略
                this.denyPolicy.reject(runnable, threadPool);
            } else {
                //將入到隊列
                runnableList.addLast(runnable);
                runnableList.notifyAll();
            }
        }
    }

    @Override
    public Runnable task() {
        synchronized (runnableList) {
            while (runnableList.isEmpty()) {
                try {
                    //如果沒有任務進來,阻塞
                    runnableList.wait();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            //從任務頭移除一個任務
           return runnableList.removeFirst();
        }
    }

    @Override
    public int size() {
        //返回線程池數量
        synchronized (runnableList) {
           return runnableList.size();
        }
    }
}
@FunctionalInterface
public interface ThreadFactory {


    /**
     * 用於創建線程
     *
     * @param runnable
     * @return
     */
    Thread createThread(Runnable runnable);

}
 初始化線程池,需要有數量控制、創建線程工廠、隊列策略等

import java.util.ArrayDeque;
import java.util.Queue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
 
public class BasicThreadPool extends Thread implements ThreadPool {

    /**
     * 初始化線程數量
     */
    private final int initSize;

    /**
     * 線程池最大線程數量
     */
    private final int maxSize;

    /**
     * 線程池核心線程數量
     */
    private final int coreSize;

    /**
     * 當前活躍的線程數量
     */
    private int activeCount;

    /**
     * 線程工廠
     */
    private final ThreadFactory threadFactory;

    /**
     * 任務隊列
     */
    private final RunnableQueue runnableQueue;
    /**
     * 是否停止線程池
     */
    private volatile boolean isShutdown = false;

    /**
     * 時間
     */
    private final long keepAliveTime;
    /**
     * 睡眠工具類
     */
    private final TimeUnit timeUnit;

    /**
     * 任務隊列
     */
    private final Queue<ThreadTask> threadQueue = new ArrayDeque();

    private final static DenyPolicy DEFAULT_DENY_POLICY = new DenyPolicy.DiscardDenyPolicy();

    private final static ThreadFactory DEFAULT_THREAD_FACTORY = new DefaultThreadFactory();

    public BasicThreadPool(int initSize, int maxSize, int coreSize, int queueSize) {
        this(initSize, maxSize, coreSize, DEFAULT_THREAD_FACTORY, queueSize, DEFAULT_DENY_POLICY, 10, TimeUnit.SECONDS);
    }

    public BasicThreadPool(int initSize, int maxSize, int coreSize, ThreadFactory defaultThreadFactory,
                           int queueSize, DenyPolicy defaultDenyPolicy, int keepAliveTime, TimeUnit timeUnit) {
        this.initSize = initSize;
        this.maxSize = maxSize;
        this.coreSize = coreSize;
        this.threadFactory = defaultThreadFactory;
        this.runnableQueue = new LinkendRunnableQueue(queueSize, defaultDenyPolicy, this);
        this.keepAliveTime = keepAliveTime;
        this.timeUnit = timeUnit;
        this.init();
    }

    /**
     * 初始化
     */
    private void init() {
        start();
        for (int i = 0; i < initSize; i++) {
            newThread();
        }
    }

    /**
     * 擴容
     */
    private void newThread() {
        InternalTask internalTask = new InternalTask(runnableQueue);
        Thread thread = this.threadFactory.createThread(internalTask);
        ThreadTask threadTask = new ThreadTask(thread, internalTask);
        threadQueue.offer(threadTask);
        this.activeCount++;
        thread.start();
    }

    private void removeThread() {
        //從線程中移除某個線程
        ThreadTask threadTask = threadQueue.remove();
        threadTask.internalTask.stop();
        this.activeCount--;
    }

    @Override
    public void run() {
        //用於維護線程數量,比如擴容、回收等工作
        while (!isShutdown && !isInterrupted()) {
            try {
                timeUnit.sleep(keepAliveTime);
            } catch (InterruptedException e) {
                isShutdown = true;
                break;
            }

            synchronized (this) {
                if (isShutdown)
                    break;
                if (runnableQueue.size() > 0 && activeCount < coreSize) {
                    for (int i = initSize; i < coreSize; i++) {
                        newThread();
                    }
                    continue;
                }


                if (runnableQueue.size() > 0 && activeCount < coreSize) {
                    for (int i = initSize; i < maxSize; i++) {
                        newThread();
                    }
                }

                if (runnableQueue.size() == 0 && activeCount > coreSize) {
                    for (int i = coreSize; i < activeCount; i++) {
                        removeThread();
                    }
                }


            }
        }
    }

    @Override
    public void execute(Runnable runnable) {
        if (this.isShutdown)
            throw new IllegalStateException("The thread pool is destroy");
        //提交到隊列
        this.runnableQueue.offer(runnable);
    }

    @Override
    public void shutdown() {
        synchronized (this) {
            if (isShutdown) {
                return;
            }
            isShutdown = true;

            threadQueue.forEach(threadTask -> {
                threadTask.internalTask.stop();
                threadTask.thread.interrupt();
            });
            this.interrupt();
        }
    }

    @Override
    public int getInitSize() {
        if (isShutdown)
            throw new IllegalStateException("The thread pool is destroy");
        return this.initSize;
    }

    @Override
    public int getMaxsize() {
        if (isShutdown)
            throw new IllegalStateException("The thread pool is destroy");
        return this.maxSize;
    }

    @Override
    public int getCoreSize() {
        if (isShutdown)
            throw new IllegalStateException("The thread pool is destroy");
        return this.coreSize;
    }

    @Override
    public int getQuenSize() {
        if (isShutdown)
            throw new IllegalStateException("The thread pool is destroy");
        return this.runnableQueue.size();
    }

    @Override
    public int getActiveCount() {
        if (isShutdown)
            throw new IllegalStateException("The thread pool is destroy");
        return this.activeCount;
    }

    @Override
    public boolean isShutdown() {
        if (isShutdown)
            throw new IllegalStateException("The thread pool is destroy");
        return this.isShutdown;
    }

    /**
     * ThreadTask只是InternalTask和Thread結合
     */
    private static class ThreadTask {
        Thread thread;
        InternalTask internalTask;

        public ThreadTask(Thread thread, InternalTask internalTask) {
            this.thread = thread;
            this.internalTask = internalTask;
        }
    }


    /**
     * 默認線程池
     */
    private static class DefaultThreadFactory implements ThreadFactory {

        private static final AtomicInteger GROUP_COUNTER = new AtomicInteger(1);

        private static final ThreadGroup group = new ThreadGroup("MyThreadPool-" + GROUP_COUNTER.getAndDecrement());

        private static final AtomicInteger COUNTER = new AtomicInteger(0);

        @Override
        public Thread createThread(Runnable runnable) {
            return new Thread(group, runnable, "thread-pool-" + COUNTER.getAndDecrement());
        }
    }
}

測試類

public class ThreadPoolTest {
    public static void main(String[] args) throws InterruptedException {
        final ThreadPool threadPool = new BasicThreadPool(10, 100, 10, 1000);


        for (int i = 0; i < 20; i++) {
            threadPool.execute(() -> {
                try {
                    TimeUnit.SECONDS.sleep(10);
                    System.out.println(Thread.currentThread().getName() + " is running and done.");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });

            for (; ; ) {
                System.out.println("getActiveCount:" + threadPool.getActiveCount());
                System.out.println("getCoreSize:" + threadPool.getCoreSize());
                System.out.println("getMaxSize:" + threadPool.getMaxsize());
                System.out.println("getRunnableQueue:" + threadPool.getQuenSize());
                System.out.println("=================================");
                TimeUnit.SECONDS.sleep(5);
            }
        }
    }
}

這裏只是思路,還存在很多缺點不在優化。

1.BasicThreadPool和Thread不應該是繼承關係,採用組合最好。

2.線程池銷燬對未返回未完成的任務,導致任務丟失。

3.BasicThreadPool構造太多,建議建造者模式

4.線程池對數量控制並沒有校驗,initSize不應該大於MaxSize

5.其他自行考慮

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