java设计思想-池化-手写线程池

模拟jdk线程池实现,自己开发一个线程池

作用
1、线程池能重用线程对象,减少创建和销毁线程时资源的开销;
2、能控制最大并发数;
3、线程池可以对线程进行管理,如定时、定期、单线程、并发数控制等

代码实现

线程池接口,方便扩展

import java.util.List;

public interface ThreadPool {

    void execute(Runnable task);

    void execute(Runnable[] task);

    void execute(List<Runnable> task);

    //返回执行任务的个数
    int getExecuteTaskNumber();

    //返回任务队列的长度 即还没处理的任务个数
    int getWaitTaskNumber();

    //返回工作线程的个数
    int getWorkThreadNumber();

    //关闭线程池
    void destory();

}

具体实现

public class ThreadPoolManager implements ThreadPool {


    //线程池中默认线程的个数为5
    private static int workerNum = 5;

    //工作线程数组
    WorkThead[] workTheads;

    //执行任务数量
    private static volatile int executeTaskNumber = 0;

    //任务队列 作为一个缓冲 List线程不安全
    private List<Runnable> taskQueue = new LinkedList<Runnable>();

    //private BlockingQueue<Runnable> taskQueue = new
    //ArrayBlockingQueue<Runnable>(1024);

    private static ThreadPoolManager threadPool;

    private AtomicLong threadNum = new AtomicLong();

    private ThreadPoolManager() {
        this(workerNum);
    }

    private ThreadPoolManager(int workerNum) {

        if (workerNum > 0) {
            ThreadPoolManager.workerNum = workerNum;
        }

        //工作线程初始化
        workTheads = new WorkThead[workerNum];

        for (int i = 0; i < ThreadPoolManager.workerNum; i++) {
            workTheads[i]= new WorkThead();
            Thread thread = new Thread(workTheads[i], "ThreadPool-worker" + threadNum.incrementAndGet());
            System.out.println("初始化线程总数" + (i + 1) + "------当前线程名称是:" + thread.getName());
            thread.start();
        }


    }

    //获取线程池
    public static ThreadPool getThreadPool() {

        return getThreadPool(ThreadPoolManager.workerNum);
    }

    public static ThreadPool getThreadPool(int workerNum) {

        if (workerNum <= 0) {
            workerNum = ThreadPoolManager.workerNum;
        }

        if (threadPool == null) {
            threadPool = new ThreadPoolManager(workerNum);
        }

        return threadPool;
    }


    @Override
    public void execute(Runnable task) {
        synchronized (taskQueue) {
            taskQueue.add(task);
            //通知 启动的线程
            taskQueue.notifyAll();
        }
    }


    @Override
    public void execute(Runnable[] tasks) {

        synchronized (taskQueue) {
            for (Runnable task : tasks) {
                taskQueue.add(task);
            }
            taskQueue.notifyAll();
        }

    }

    @Override
    public void execute(List<Runnable> tasks) {

        synchronized (taskQueue) {
            for (Runnable task : tasks) {
                taskQueue.add(task);
            }
            taskQueue.notifyAll();
        }
    }

    @Override
    public int getExecuteTaskNumber() {

        return executeTaskNumber;
    }

    @Override
    public int getWaitTaskNumber() {
        return taskQueue.size();
    }

    @Override
    public int getWorkThreadNumber() {
        return workerNum;
    }

    /**
     * 线程池销毁
     */
    @Override
    public void destory() {

        while (!taskQueue.isEmpty()) {

            try {
                //不断检测任务队列是否全部执行
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        for (int i = 0; i < workerNum; i++) {
            workTheads[i].stopWorker();
            workTheads[i] = null;
        }

        threadPool = null;
        taskQueue.clear();
    }


    @Override
    public String toString() {
        return "当前工作线程数:" + workerNum +
                ", 已完成任务数:" + executeTaskNumber +
                ", 等待任务数量:" + getWaitTaskNumber();
    }

    private class WorkThead extends Thread {

        //该工作线程是否有效 用于结束该工作线程
        private boolean isRunning = true;


        @Override
        public void run() {
            super.run();

            //队列同步机制synchronized
            //接收队列当中的任务对象 Runnable 类型
            Runnable r = null;

//线程无效 结束run方法 线程没用了
            while (isRunning) {
                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();//执行任务
                    }

                    executeTaskNumber++;
                    r = null;

                }

            }




        }

        //停止工作 让该线程自然执行完run方法 自然结束
        public void stopWorker() {
            isRunning = false;
        }
    }

}

测试类

import javafx.concurrent.Task;

import java.util.ArrayList;
import java.util.List;

public class ThreadPoolTest {

    public static void main(String[] args) {
        ThreadPool t = ThreadPoolManager.getThreadPool(6);

        List<Runnable> taskList = new ArrayList<Runnable>();

        for (int i = 0; i < 100; i++) {
            taskList.add(new Task());
        }
        t.execute(taskList);
        System.out.println(t);
        t.destory();//所有线程执行完才destory
        System.out.println(t);

    }

    //任务类

    static class Task implements Runnable {

        private static volatile int i = 1;

        @Override
        public void run() {
            System.out.println("当前处理的线程是:" + Thread.currentThread().getName() + " 执行任务" + (i++) + " 完成");
        }
    }


}

运行结果

这里写图片描述

这里写图片描述

总结
自己实现线程池,要注意线程安全、线程池销毁的合理控制,防止出现死锁等情况,当然,这只是模仿jdk线程池中的一种(FixedThreadPool 固定大小的线程池)实现,还可以模仿SingleThreadPool、CachedThreadPool、ScheduledThreadPool等jdk线程池 自行扩展

猜你喜欢

转载自blog.csdn.net/qq_16038125/article/details/80225610