自定义线程池

线程池的代码是简单线程池的实现,里面功能完成了:

  • 1.使用固定线程,执行任务
  • 2.实现线程池的拒绝策略,以及停止线程池
  • 3.线程池的扩容以及回收

上面的功能分成三部分完成,有三个版本的代码实现,具体步骤,在代码上有描述:

1.使用固定线程,执行任务

 1.封装Thread对象WorkThread,使其具有生命状态;
 2.初始化创建size个WorkThread,存储到WORK_THREAD_QUEUE;
 3.创建任务(Runnable)提交接口,将任务提交到TASK_QUEUE;
import chapter3.ThreadUtil;

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

/**
 * 实现线程池基本功能,使用固定线程,执行任务
 *
 * @author: mahao
 * @date: 2019/8/15
 */
public class ThreadPool1 {

    /*
    1.封装Thread对象WorkThread,使其具有生命状态;
    2.初始化创建size个WorkThread,存储到WORK_THREAD_QUEUE;
    3.创建任务(Runnable)提交接口,将任务提交到TASK_QUEUE;
     */

    private static final int DEFAULT_SIZE = 10;//默认线程中的数量
    private static long seq = 0;
    private static final String WORK_THREAD_PREFIX = "WORK_THREAD_";//默认线程中的数量

    private final int size;//线程池中的线程数量

    private final LinkedList<Runnable> TASK_QUEUE = new LinkedList<>();//任务队列
    private final List<WorkThread> WORK_THREAD_QUEUE = new ArrayList<>(DEFAULT_SIZE);//线程队列

    public ThreadPool1() {
        this(DEFAULT_SIZE);
    }

    public ThreadPool1(int size) {
        this.size = size;
        init();
    }

    //初始化创建size个工作线程,并启动
    private void init() {
        for (int i = 0; i < size; i++) {
            WorkThread wt = createWorkThread();
            wt.start();
        }
    }

    //提交任务
    public void submit(Runnable task) {

        synchronized (TASK_QUEUE) {
            // System.out.println("submit -#- add task,current TASK_QUEUE size : " + TASK_QUEUE.size() + " >> begin");
            TASK_QUEUE.addLast(task);
            TASK_QUEUE.notifyAll();//唤醒等待的workThread
            //System.out.println("submit -#- add task,current TASK_QUEUE size : " + TASK_QUEUE.size() + " >> end");
        }


    }


    //创建工作线程
    private WorkThread createWorkThread() {
        WorkThread workThread = new WorkThread(WORK_THREAD_PREFIX + (seq++));
        WORK_THREAD_QUEUE.add(workThread);
        return workThread;
    }

    private class WorkThread extends Thread {

        public Status statu = Status.FREE;//初始创建是空闲的
        private Runnable task;//工作线程负责执行的任务

        public WorkThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            //当线程未被关闭是,就一直运行
            OUTLINE:
            while (this.statu != Status.DEAD) {
                synchronized (TASK_QUEUE) {
                    while (TASK_QUEUE.isEmpty()) {//任务队列中为空,线程等待
                        try {
                            System.err.println(ThreadUtil.getName() + " be waiting, status: " + statu);
                            this.statu = Status.WAITING;//为以后中断线程使用,标记线程可中断,没有任务执行
                            TASK_QUEUE.wait();
                        } catch (InterruptedException e) {
                            System.err.println(ThreadUtil.getName() + " be interrupted, status: " + statu);
                            e.printStackTrace();
                            //当前线程发生中断请求,就跳转到线程循环外,判断是否线程状态是关闭了;
                            break OUTLINE;
                        }
                    }
                    //不为空,取出任务,然后设置工作线程状态
                    task = TASK_QUEUE.removeFirst();
                }

                //可以与其他线程并发执行任务,放在同步代码块之外
                if (task != null) {
                    this.statu = Status.RUNNING;
                    task.run();//运行任务
                    //运行结束后,任务值为空,线程状态置为空闲
                    this.statu = Status.FREE;
                    task = null;
                }

            }
        }

        public void close() {
            System.out.println("WorkThread.close -#- be close, current status :" + statu);
            this.statu = Status.DEAD;
        }
    }

    private enum Status {

        FREE, RUNNING, WAITING, DEAD
    }

}

class TestThreadPool1 {

    public static void main(String[] args) {
        ThreadPool1 threadPool1 = new ThreadPool1(10);
        for (int i = 0; i < 40; i++) {
            final int no = i;
            threadPool1.submit(() -> {
                System.out.println("WorkThread.run -#- is running , current WorkThread name :" + ThreadUtil.getName() + " , task no : " + no + "  >> start");
                System.out.println("main -#- task submit ,no : " + no);
                ThreadUtil.sleep(new Random().nextInt(10) * 1000);
                System.out.println("WorkThread.run -#- is running , current WorkThread name :" + ThreadUtil.getName() + " , task no : " + no + "  >> end");
            });
        }
    }
}

2.实现线程池的拒绝策略,以及停止线程池

拒绝策略:
      1.在提交任务的接口,检测线程池中任务队列的个数,大于限制,就不允许添加
停止线程:
      1.创建线程池对外暴露接口,外部调用
      2.在关闭接口中,遍历工作线程,中断workThread线程
import chapter3.ThreadUtil;

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

/**
 * 实现线程池的拒绝策略,以及停止线程池
 *
 * @author: mahao
 * @date: 2019/8/15
 */
public class ThreadPool2 {
     /*
    拒绝策略:
        1.在提交任务的接口,检测线程池中任务队列的个数,大于限制,就不允许添加
    停止线程:
        1.创建线程池对外暴露接口,外部调用
        2.在关闭接口中,遍历工作线程,中断workThread线程
     */

    private static final int DEFAULT_SIZE = 10;//默认线程中的数量
    private static long seq = 0;
    private static final String WORK_THREAD_PREFIX = "WORK_THREAD_";//默认线程中的数量
    private static final int DEFAULT_TASK_QUEUE_LIMIT_SIZE = 100;
    public static final DiscardPolicy default_discardPolicy = (task) -> {
        throw new DiscardException("discard the submit and throw exception... ");
    };

    private final int size;//线程池中的线程数量
    private final int taskQueueSize;//限制任务队列数
    private final LinkedList<Runnable> TASK_QUEUE = new LinkedList<>();//任务队列
    private final List<WorkThread> WORK_THREAD_QUEUE = new ArrayList<>(DEFAULT_SIZE);//线程队列
    private final DiscardPolicy discardPolicy;
    private boolean isClose = false;

    public ThreadPool2() {
        this(DEFAULT_SIZE, DEFAULT_TASK_QUEUE_LIMIT_SIZE, default_discardPolicy);
    }

    /**
     * @param size          执行线程的数量
     * @param taskQueueSize 任务队列限制的大小
     * @param discardPolicy 拒绝策略
     */
    public ThreadPool2(int size, int taskQueueSize, DiscardPolicy discardPolicy) {
        this.size = size;
        this.taskQueueSize = taskQueueSize;
        this.discardPolicy = discardPolicy;
        init();
    }

    //初始化创建size个工作线程,并启动
    private void init() {
        for (int i = 0; i < size; i++) {
            WorkThread wt = createWorkThread();
            wt.start();
        }
    }

    //提交任务
    public void submit(Runnable task) {
        if (isClose) {
            throw new IllegalStateException("Thread pool be closed ... ");
        }
        synchronized (TASK_QUEUE) {
            if (TASK_QUEUE.size() > taskQueueSize) {
                discardPolicy.discard(task);
            } else {
                // System.out.println("submit -#- add task,current TASK_QUEUE size : " + TASK_QUEUE.size() + " >> begin");
                TASK_QUEUE.addLast(task);
                TASK_QUEUE.notifyAll();//唤醒等待的workThread
                //System.out.println("submit -#- add task,current TASK_QUEUE size : " + TASK_QUEUE.size() + " >> end");
            }
        }
    }

    /**
     * 关闭线程池:
     * 1.中断所有没有执行任务的线程
     * 2.等待正在执行任务的线程,然后关闭
     */
    public void shutdown() throws InterruptedException {
        System.out.println("begin shutdowm thread pool ... ");
        while (!TASK_QUEUE.isEmpty()) {//等待任务队列,执行结束
            Thread.sleep(20);
        }
        int size = WORK_THREAD_QUEUE.size();
        while (size > 0) {
            for (WorkThread w : WORK_THREAD_QUEUE) {
                if (w.statu == Status.WAITING) {
                    w.interrupt();
                    w.close();
                    size--;
                } else {
                    Thread.sleep(20);
                }
            }
        }
        isClose = true;
    }

    //创建工作线程
    private WorkThread createWorkThread() {
        WorkThread workThread = new WorkThread(WORK_THREAD_PREFIX + (seq++));
        WORK_THREAD_QUEUE.add(workThread);
        return workThread;
    }

    private class WorkThread extends Thread {

        public Status statu = Status.FREE;//初始创建是空闲的
        private Runnable task;//工作线程负责执行的任务

        public WorkThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            //当线程未被关闭是,就一直运行
            OUTLINE:
            while (this.statu != Status.DEAD) {
                synchronized (TASK_QUEUE) {
                    while (TASK_QUEUE.isEmpty()) {//任务队列中为空,线程等待
                        try {
                            System.err.println(ThreadUtil.getName() + " be waiting, status: " + statu);
                            this.statu = Status.WAITING;//为以后中断线程使用,标记线程可中断,没有任务执行
                            TASK_QUEUE.wait();
                        } catch (InterruptedException e) {
                            System.err.println(ThreadUtil.getName() + " be interrupted, status: " + statu);
                            //e.printStackTrace();
                            //当前线程发生中断请求,就跳转到线程循环外,判断是否线程状态是关闭了;
                            break OUTLINE;
                        }
                    }
                    //不为空,取出任务,然后设置工作线程状态
                    task = TASK_QUEUE.removeFirst();
                }

                //可以与其他线程并发执行任务,放在同步代码块之外
                if (task != null) {
                    this.statu = Status.RUNNING;
                    task.run();//运行任务
                    //运行结束后,任务值为空,线程状态置为空闲
                    this.statu = Status.FREE;
                    task = null;
                }

            }
        }

        public void close() {
            System.out.println("**  ** WorkThread.close -#-  " + getName() + " is closeing , current status :" + statu);
            this.statu = Status.DEAD;
        }
    }

    private enum Status {

        FREE, RUNNING, WAITING, DEAD
    }

    //拒绝策略接口
    public interface DiscardPolicy {
        void discard(Runnable task) throws DiscardException;
    }

    public static class DiscardException extends RuntimeException {
        public DiscardException(String msg) {
            super(msg);
        }
    }
}

class TestThreadPool2 {

    public static void main(String[] args) throws InterruptedException {
        ThreadPool2 threadPool2 = new ThreadPool2(10, 40, ThreadPool2.default_discardPolicy);

        for (int i = 0; i < 40; i++) {
            final int no = i;
            threadPool2.submit(() -> {
                System.out.println("WorkThread.run -#- is running , current WorkThread name :" + ThreadUtil.getName() + " , task no : " + no + "  >> start");
                System.out.println("main -#- task submit ,no : " + no);
                ThreadUtil.sleep(3_000);
                System.out.println("WorkThread.run -#- is running , current WorkThread name :" + ThreadUtil.getName() + " , task no : " + no + "  >> end");
            });
        }
        ThreadUtil.sleep(10000);

        threadPool2.shutdown();

        threadPool2.submit(() -> {
        });
    }
}

3.增加线程池的扩容以及回收

扩容与回收
        1.更改线程池也为线程,当初始化线程完毕后,启动扩容方法
        2.扩容:
            1.当TASK_QUEUE大于当前线程数量,扩容到指定大小
            2.当TASK_QUEUE为空时,减少工作线程数量
import chapter3.ThreadUtil;

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

/**
 * 增加线程池的扩容以及回收
 *
 * @author: mahao
 * @date: 2019/8/15
 */
public class ThreadPool3 extends Thread {

    /*
        扩容与回收
        1.更改线程池也为线程,当初始化线程完毕后,启动扩容方法
        2.扩容:
            1.当TASK_QUEUE大于当前线程数量,扩容到指定大小
            2.当TASK_QUEUE为空时,减少工作线程数量

     */

    //private static final int DEFAULT_SIZE = 10;//默认线程中的数量
    private static long seq = 0;
    private static final String WORK_THREAD_PREFIX = "WORK_THREAD_";//默认线程中的数量
    private static final int DEFAULT_TASK_QUEUE_LIMIT_SIZE = 100;
    public static final ThreadPool3.DiscardPolicy default_discardPolicy = (task) -> {
        throw new ThreadPool3.DiscardException("discard the submit and throw exception... ");
    };

    private int size;//线程池中的线程数量
    private final int taskQueueSize;//限制任务队列数
    private final LinkedList<Runnable> TASK_QUEUE = new LinkedList<>();//任务队列
    private final List<WorkThread> WORK_THREAD_QUEUE = new ArrayList<>();//线程队列
    private final ThreadPool3.DiscardPolicy discardPolicy;
    private boolean isClose = false;//标记线程池是否已经关闭

    private final int min;
    private int active;
    private final int max;

    public ThreadPool3() {
        this(3, 5, 10, DEFAULT_TASK_QUEUE_LIMIT_SIZE, default_discardPolicy);
    }

    /**
     * @param min           线程池中的最小数量
     * @param active        线程中的活跃数量
     * @param max           线程池中的最大数量
     * @param taskQueueSize 任务队列限制的大小
     * @param discardPolicy 拒绝策略
     */
    public ThreadPool3(int min, int active, int max, int taskQueueSize, DiscardPolicy discardPolicy) {
        this.size = size;
        this.taskQueueSize = taskQueueSize;
        this.discardPolicy = discardPolicy;
        this.min = min;
        this.active = active;
        this.max = max;

        init();

        this.start();//初始化完毕后,启动维护线程池大小的线程
    }

    //初始化创建size个工作线程,并启动
    private void init() {
        for (int i = 0; i < min; i++) {
            System.out.println("init --create -- " + i);
            WorkThread wt = createWorkThread();
            wt.start();
        }
        this.size = min;
    }

    @Override
    public void run() {
        while (!isClose) {//当线程池没被关闭

            System.out.printf("-- Pool#Min:%d , Active:%d , Max:%d; current:%d , WORK_THREAD_QUEUE size:%d , TASK_QUEUE size:%d\n",
                    min, active, max, size, WORK_THREAD_QUEUE.size(), TASK_QUEUE.size());
            try {
                Thread.sleep(2000);
                //扩容
                if (TASK_QUEUE.size() > active && size < active) {
                    for (int i = size; i < active; i++) {
                        WorkThread w = createWorkThread();
                        w.start();
                    }
                    size = active;
                    System.out.println("--- TASK_QUEUE.size() > active  ---");
                } else if (TASK_QUEUE.size() > max && size < max) {
                    for (int i = size; i < max; i++) {
                        WorkThread w = createWorkThread();
                        w.start();
                    }
                    size = max;
                    System.out.println("---  TASK_QUEUE.size() > max  ---");
                }

                //减容
                if (TASK_QUEUE.isEmpty() && active < size) {
                    System.out.println("===========Reduce===========");
                    synchronized (TASK_QUEUE) {
                        int releaseSize = size - active;
                        for (Iterator<WorkThread> it = WORK_THREAD_QUEUE.iterator(); it.hasNext(); ) {
                            if (releaseSize <= 0)
                                break;
                            WorkThread w = it.next();
                            if (w.statu == Status.WAITING) {
                                w.close();
                                w.interrupt();
                                it.remove();
                                releaseSize--;
                            }
                            size = WORK_THREAD_QUEUE.size();

                        }
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    //提交任务
    public void submit(Runnable task) {
        if (isClose) {
            throw new IllegalStateException("Thread pool be closed ... ");
        }
        synchronized (TASK_QUEUE) {
            if (TASK_QUEUE.size() > taskQueueSize) {
                discardPolicy.discard(task);
            } else {
                // System.out.println("submit -#- add task,current TASK_QUEUE size : " + TASK_QUEUE.size() + " >> begin");
                TASK_QUEUE.addLast(task);
                TASK_QUEUE.notifyAll();//唤醒等待的workThread
                //System.out.println("submit -#- add task,current TASK_QUEUE size : " + TASK_QUEUE.size() + " >> end");
            }
        }
    }

    /**
     * 关闭线程池:
     * 1.中断所有没有执行任务的线程
     * 2.等待正在执行任务的线程,然后关闭
     */
    public void shutdown() throws InterruptedException {
        System.out.println("begin shutdowm thread pool ... ");
        while (!TASK_QUEUE.isEmpty()) {//等待任务队列,执行结束
            Thread.sleep(20);
        }
        int size = WORK_THREAD_QUEUE.size();
        while (size > 0) {
            for (ThreadPool3.WorkThread w : WORK_THREAD_QUEUE) {
                if (w.statu == ThreadPool3.Status.WAITING) {
                    w.interrupt();
                    w.close();
                    size--;
                } else {
                    Thread.sleep(20);
                }
            }
        }
        isClose = true;
    }

    //创建工作线程
    private ThreadPool3.WorkThread createWorkThread() {
        ThreadPool3.WorkThread workThread = new ThreadPool3.WorkThread(WORK_THREAD_PREFIX + (seq++));
        WORK_THREAD_QUEUE.add(workThread);
        return workThread;
    }

    private class WorkThread extends Thread {

        public ThreadPool3.Status statu = ThreadPool3.Status.FREE;//初始创建是空闲的
        private Runnable task;//工作线程负责执行的任务

        public WorkThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            //当线程未被关闭是,就一直运行
            OUTLINE:
            while (this.statu != ThreadPool3.Status.DEAD) {
                synchronized (TASK_QUEUE) {
                    while (TASK_QUEUE.isEmpty()) {//任务队列中为空,线程等待
                        try {
                            //System.err.println(ThreadUtil.getName() + " be waiting, status: " + statu);
                            this.statu = ThreadPool3.Status.WAITING;//为以后中断线程使用,标记线程可中断,没有任务执行
                            TASK_QUEUE.wait();
                        } catch (InterruptedException e) {
                            System.err.println(ThreadUtil.getName() + " be interrupted, status: " + statu);
                            //e.printStackTrace();
                            //当前线程发生中断请求,就跳转到线程循环外,判断是否线程状态是关闭了;
                            break OUTLINE;
                        }
                    }
                    //不为空,取出任务,然后设置工作线程状态
                    task = TASK_QUEUE.removeFirst();
                }

                //可以与其他线程并发执行任务,放在同步代码块之外
                if (task != null) {
                    this.statu = ThreadPool3.Status.RUNNING;
                    task.run();//运行任务
                    //运行结束后,任务值为空,线程状态置为空闲
                    this.statu = ThreadPool3.Status.FREE;
                    task = null;
                }

            }
        }

        public void close() {
            System.out.println("**  ** WorkThread.close -#-  " + getName() + " is closeing , current status :" + statu);
            this.statu = ThreadPool3.Status.DEAD;
        }
    }

    private enum Status {

        FREE, RUNNING, WAITING, DEAD
    }

    //拒绝策略接口
    public interface DiscardPolicy {
        void discard(Runnable task) throws ThreadPool3.DiscardException;
    }

    public static class DiscardException extends RuntimeException {
        public DiscardException(String msg) {
            super(msg);
        }
    }
}

class TestThreadPool3 {

    public static void main(String[] args) throws InterruptedException {
        ThreadPool3 threadPool3 = new ThreadPool3(3, 10, 20, 200, ThreadPool3.default_discardPolicy);

        for (int i = 0; i < 40; i++) {
            final int no = i;
            threadPool3.submit(() -> {
                System.out.println("WorkThread.run -#- is running , current WorkThread name :" + ThreadUtil.getName() + " , task no : " + no + "  >> start");
                //System.out.println("main -#- task submit ,no : " + no);
                ThreadUtil.sleep(5_000);
                //System.out.println("WorkThread.run -#- is running , current WorkThread name :" + ThreadUtil.getName() + " , task no : " + no + "  >> end");
            });
        }

        ThreadUtil.sleep(15_000);

        for (int i = 40; i < 100; i++) {
            final int no = i;
            threadPool3.submit(() -> {
                System.out.println("WorkThread.run -#- is running , current WorkThread name :" + ThreadUtil.getName() + " , task no : " + no + "  >> start");
                // System.out.println("main -#- task submit ,no : " + no);
                ThreadUtil.sleep(3_000);
                // System.out.println("WorkThread.run -#- is running , current WorkThread name :" + ThreadUtil.getName() + " , task no : " + no + "  >> end");
            });
        }

        ThreadUtil.sleep(15_000);
        threadPool3.shutdown();

        threadPool3.submit(() -> {

        });
    }
}

GitHub源码地址

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值