天天看點

java 手寫簡化版線程池

線程池

第一步:設定線程池基本變量

//給定一個初始池大小
    private static int workNum = 5;
	//完成線程池數量
    private static volatile int finished_task = 0;
	
    private WorkThread[] workThreads;
	//用于放置線程的池子
    private  List<Runnable> taskQueue = new LinkedList<>();

    private static ThreadPool threadPool;
           

第二步:初始化線程池大小

public ThreadPool(int workNum){
        ThreadPool.workNum = workNum;
        workThreads = new WorkThread[workNum];
        for (int i = 0; i < workNum; i++) {
            workThreads[i] = new WorkThread();
            workThreads[i].start();// 開啟線程池中的線程
        }
    }
 // worker_num<=0建立預設的工作線程個數
    public static ThreadPool getThreadPool(int worker_num1) {
        if (worker_num1 <= 0)
            worker_num1 = ThreadPool.workNum;
        if (threadPool == null)
            threadPool = new ThreadPool(worker_num1);
        return threadPool;
    }
           

第三步:将線程放入池中緩存和執行任務

// 執行任務,其實隻是把任務加入任務隊列,什麼時候執行有線程池管理器覺定
    public void execute(Runnable[] task) {
        synchronized (taskQueue) {
            for (Runnable run : task){
                taskQueue.add(run);
                taskQueue.notify();
            }
        }
    }
 private class WorkThread extends Thread {
        // 該工作線程是否有效,用于結束該工作線程
        private boolean isRunning = true;

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

第四步:結束回收線程

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

           

測試代碼:

public static void main(String[] args) {
        // 建立3個線程的線程池
        ThreadPool t = ThreadPool.getThreadPool(3);
        t.execute( new Runnable[] { new Task(), new Task(), new Task() });
        t.execute(new Runnable[] { new Task(), new Task(), new Task() });
        System.out.println(t);
        t.destroy();// 所有線程都執行完成才destory
        System.out.println(t);
    }

    // 任務類
    static class Task implements Runnable {
        private static volatile int i = 1;

        @Override
        public void run() {// 執行任務
            System.out.println("任務 " + (i++) + " 完成");
        }
    }