手写简单线程池

160 阅读1分钟

为什么要使用线程池

1.可以降低线程创建和销毁的资源消耗

2.可以提高响应速度,免去部分线程的创建和销毁时间

3.更好的管理线程

代码演示

package com.ecit.back.showhystrix;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * @author Y2M
 * @createTime 2021/7/13
 * @comment
 */
public class CustomerThreadPool {

    /*默认线程池中的线程的数量*/
    private static final int WORK_NUM = 5;

    /*默认处理任务的数量*/
    private static final int TASK_NUM = 100;

    /*存放任务*/
    private BlockingDeque<Runnable> taskQueue = null;

    /*保存线程的集合*/
    private Set<WorkThread> workThreads = null;

    /*线程数量*/
    private int workNumber;

    /*任务数量*/
    private int taskNumber;

    public CustomerThreadPool(){
        this(WORK_NUM,TASK_NUM);
    }

    public CustomerThreadPool(int workNumber,int taskNumber){
        if (taskNumber<=0){
            taskNumber = TASK_NUM;
        }
        if (workNumber<=0){
            workNumber = WORK_NUM;
        }
        this.taskQueue = new LinkedBlockingDeque<>(taskNumber);
        this.workNumber = workNumber;
        this.taskNumber = taskNumber;
        workThreads = new HashSet<>();
        //工作线程准备好了
        //启动一定数量的线程数,从队列中获取任务处理
        for (int i = 0; i < workNumber; i++) {
            WorkThread workThread = new WorkThread("thread_"+i);
            workThread.start();
            workThreads.add(workThread);
        }
    }

    /**
     * 线程池执行任务的方法,其实就是往BlockingQueue中添加元素
     * @param task
     */
    public void execute(Runnable task) {
        try {
            taskQueue.put(task);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    /**
     * 销毁线程池
     */
    public void destroy(){
        System.out.println("ready close pool...");
        for (WorkThread workThread : workThreads) {
            workThread.stopWorker();
            workThread = null;//help gc
        }
        workThreads.clear();
    }

    private class WorkThread extends Thread{
        public WorkThread(String name){
            super();
            setName(name);
        }
        @Override
        public void run() {
            while (!interrupted()) {
                try {
                    Runnable runnable = taskQueue.take();//获取任务
                    if (runnable !=null) {
                        System.out.println(getName()+" ready execute:"+runnable.toString());
                        //执行任务
                        runnable.run();
                    }
                    //help gc
                    runnable = null;
                } catch (Exception e) {
                    interrupt();
                    e.printStackTrace();
                }
            }
        }

        public void stopWorker(){
            interrupt();
        }
    }
}

package com.ecit.back.showhystrix;

/**
 * @author Y2M
 * @createTime 2021/7/13
 * @comment
 */
public class TestMySelfThreadPool {

    private static final int TASK_NUM = 50;//任务的个数

    public static void main(String[] args) {
        CustomerThreadPool myPool = new CustomerThreadPool(3,50);
        for (int i=0;i<TASK_NUM;i++) {
            myPool.execute(new MyTask("task_"+i));
        }

    }

    static class MyTask implements Runnable{

        private String name;
        public MyTask(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }


        @Override
        public void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("task :"+name+" end...");

        }

        @Override
        public String toString() {
            // TODO Auto-generated method stub
            return "name = "+name;
        }
    }

}