简版ThreadPool

看了线程池的源码,理解了其大概流程。于是乎手写一个简单版ThreadPool。几个简单的功能就是控制线程数,线程并发处理任务,结束线程池。虽然功能不多,但是体现了线程池的主要功能流程。当然也没有像系统线程池一样采用CAS,而是直接用synchronized处理并发。其他细节也一概略过。主要用于理解其流程。

public class ThreadPool implements Executor {

    private AtomicInteger count = new AtomicInteger(0);
    private int mCode;
    //线程集合
    private HashSet works = new HashSet<>();
    private LinkedBlockingQueue workQueue;

    public ThreadPool(int code) {
        mCode = code;
        workQueue = new LinkedBlockingQueue<>();
    }
    //接收任务
    @Override
    public void execute(Runnable command) {
        synchronized (workQueue) {
            if (isShutdown) {
                return;
            }
        }
        //如果线程数没有达到核心线程数,开启新线程
        if (count.get() < mCode) {
            count.getAndAdd(1);
            addWorker(command);
            return;
        }
        //如果线程数已经开启核心线程数,放入队列
        workQueue.add(command);

    }

    private void addWorker(Runnable command) {
        Worker worker = new Worker(command);
        works.add(worker);
        worker.thread.start();
    }

    public class Worker implements Runnable {
        public Thread thread;
        public Runnable firstTask;

        public Worker(Runnable firstTask) {
            this.thread = new Thread(this);
            this.firstTask = firstTask;
        }
        @Override
        public void run() {
            Runnable task = firstTask;
                while(!isShutdown) {
                    //一直不断的获取任务
                    while ((task != null || (task = getTask()) != null)) {
                        task.run();
                        task = null;
                    }
                }
                System.out.println(Thread.currentThread().getName() + "结束");
            
        }
    }

    Runnable getTask(){
        synchronized (workQueue) {
            /**
             * 如果已经执行了shotDown方法,并且任务队列没有任务了。就不用调用take方法了
             */
            if (isShutdown && workQueue.isEmpty()) {
                return null;
            }
            try {
                //阻塞式获取任务,没有任务则等待
                return workQueue.take();
            } catch (InterruptedException e) {
                System.out.println("InterruptedException");
                return null;
            }
        }

    }

    private volatile boolean isShutdown = false;

    public void shutdown() {
        synchronized (workQueue) {
            isShutdown = true;
        }
    }
}

测试代码

public class TheadPoolTest {
    
    static AtomicInteger count = new AtomicInteger(0); 
    public static void main(String[] args) {
            testTheadPool();
    }
    
    private static void testTheadPool() {
        ThreadPool threadpool = new ThreadPool(4);
        for(int i=0;i<10;i++) {
            threadpool.execute(new Runnable() {
                @Override
                public void run() {
                    final int task = count.getAndAdd(1);
                    System.out.println(Thread.currentThread().getName()+"****执行任务"+task);;
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        System.out.println("sleep InterruptedException");
                    }
                    System.out.println(Thread.currentThread().getName()+">>>>执行完成任务"+task);;
                }
            });
        }
        threadpool.shutdown();
    }
}

输出

Thread-0****执行任务0
Thread-2****执行任务2
Thread-1****执行任务1
Thread-3****执行任务3
Thread-2>>>>执行完成任务2
Thread-0>>>>执行完成任务0
Thread-2****执行任务4
Thread-0****执行任务5
Thread-1>>>>执行完成任务1
Thread-1****执行任务6
Thread-3>>>>执行完成任务3
Thread-3****执行任务7
Thread-0>>>>执行完成任务5
Thread-1>>>>执行完成任务6
Thread-1****执行任务9
Thread-2>>>>执行完成任务4
Thread-3>>>>执行完成任务7
Thread-3结束
Thread-2结束
Thread-0****执行任务8
Thread-1>>>>执行完成任务9
Thread-1结束
Thread-0>>>>执行完成任务8
Thread-0结束

代码比较简单,也易于理解。当然还有其他功能比如支持最大任务,任务满了是拒绝还是抛异常,是否需要缓存线程,以及如何不用synchronized而实现高并发等细节,则需细看ThreadPoolExecutor源码

你可能感兴趣的:(简版ThreadPool)