深入理解线程池 && 制作一个线程池

1线程池是什么?

线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。对于一个队列的任务,如果将每个任务都创建一个进行任务处理,那有多少个任务就会创建多少个线程,每个线程在其生命周期只能执行一次对应的任务,并且重复的创建销毁线程会有额外的资源消耗,进而影响缓存局部性和整体性能。
在这里插入图片描述
而线程池中维护着多个线程,这些线程等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。

在这里插入图片描述

2线程池构造函数

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue)

在构造线程池函数时,需要传入核心线程个数,最大线程个数,等待时间,参数时间单位以及任务队列。
corePoolSize - 核心线程数是主要工作的线程个数,即使空闲时仍保留在池中的线程数。
maximumPoolSize - 线程池中允许存在的最大线程数。
keepAliveTime - 当线程数大于核心时,这是多余的空闲线程在终止之前等待新任务的最大时间。
unit - keepAliveTime参数的时间单位。
workQueue - 在执行任务之前用于保存任务的队列。 该队列将仅保存execute方法提交的Runnable任务

3制作一个线程池

新建一个ThreadPool类,添加核心线程数,任务队列容量,和装线程与任务的集合

 // 核心线程数量
    int Defaultworkthrednum;
    // 任务队列容量
    int Defaulttasknum ;
    static List<WorkThread> cthreads;// 线程集合
    static BlockingQueue<Runnable> taskQueue;// 任务阻塞队列
    ThreadPool(int Defaultworkthrednum , int Defaulttasknum){
        cthreads = new ArrayList<>();
        taskQueue = new ArrayBlockingQueue<>(Defaulttasknum);
        this.Defaulttasknum=Defaulttasknum;
        this.Defaultworkthrednum=Defaultworkthrednum;
    }

添加一个启动线程的方法

  void startPool() {
        for (int i = 0; i < Defaultworkthrednum; i++) {
            WorkThread workThread = new WorkThread("No." + i,i);
            workThread.start();
            cthreads.add(workThread);
        }
    }

添加一个向任务队列中添加任务的方法

 void addTask(Runnable task) {
        try {
            taskQueue.put(task);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

添加一个停止线程工作的方法

void stopPool() {
        for (int i = 0; i <cthreads.size() ; i++) {
            System.out.println(cthreads.get(i).getName()+"  stop pool");
            cthreads.get(i).isStop=true;
            cthreads.get(i).interrupt();
        }
    }

创建一个工作线程的类

public class WorkThread extends Thread{
    String name;
    int id;
    public WorkThread(String s,int id) {
        this.name=s;
        this.id=id;
    }
    boolean isStop = false;

    @Override
    public void run() {
        System.out.println("线程"+name+"开始工作");
        while (!isStop) {
            System.out.println("任务池中还有:" + ThreadPool.taskQueue.size());
            try {
                if(TaskE.doneJob>=500){

                }else {
                    Runnable runnable = ThreadPool.taskQueue.take();
                    System.out.println("线程"+name+"获取了"+runnable.toString());
                    runnable.run();
                    System.gc();
                }
                // 获取任务
            } catch (InterruptedException e) {
                //e.printStackTrace();
            }
        }
    }
}

用主程序测试线程池

public class TaskE {
    static int mm = 0;
    static int doneJob=0;
    static boolean wa = true;
    public static void main(String[] args) {
        int i = 0;
        ThreadPool tp = new ThreadPool(5,10);
        Thread t = new Thread(new Runnable(){
            int num = 0;
            @Override
            public void run() {
                while (num<20) {
                    num++;
                    mm=num;
                    tp.addTask(new Runnable() {
                        String taskName = "任务" + num + "号!";

                        @Override
                        public void run() {
                            System.out.println(taskName + "处理完成!!");
                            doneJob++;
                        }

                        @Override
                        public String toString() {
                            return taskName;
                        }
                    });
                    System.err.println("任务ADD"+num);
                }
            }
        });
        t.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        tp.startPool();
        while(doneJob <19){
            System.out.print("");
        }

        tp.stopPool();
    }
}

最后输出结果

任务ADD1
任务ADD2
任务ADD3
任务ADD4
任务ADD5
任务ADD6
任务ADD7
任务ADD8
任务ADD9
任务ADD10
线程No.0开始工作
线程No.2开始工作
线程No.1开始工作
任务池中还有:10
线程No.3开始工作
任务池中还有:10
线程No.4开始工作
任务池中还有:10
线程No.1获取了任务2号!
任务池中还有:9
线程No.4获取了任务4号!
任务4号!处理完成!!
任务池中还有:9
任务ADD11
任务ADD12
任务ADD13
任务ADD14
任务ADD15
任务ADD16
线程No.3获取了任务5号!
任务5号!处理完成!!
线程No.0获取了任务1号!
任务1号!处理完成!!
任务池中还有:10
线程No.0获取了任务6号!
任务6号!处理完成!!
任务池中还有:10
线程No.3获取了任务7号!
任务7号!处理完成!!
任务池中还有:9
任务池中还有:10
线程No.3获取了任务9号!
任务9号!处理完成!!
任务2号!处理完成!!
任务池中还有:10
任务ADD17
任务ADD18
任务ADD19
任务ADD20
线程No.3获取了任务10号!
任务10号!处理完成!!
线程No.2获取了任务3号!
任务池中还有:10
线程No.3获取了任务11号!
任务11号!处理完成!!
任务池中还有:10
线程No.1获取了任务12号!
任务12号!处理完成!!
线程No.4获取了任务8号!
任务8号!处理完成!!
任务池中还有:10
线程No.0获取了任务13号!
任务13号!处理完成!!
任务池中还有:7
任务池中还有:8
线程No.4获取了任务15号!
任务池中还有:8
线程No.1获取了任务16号!
任务16号!处理完成!!
任务池中还有:8
线程No.3获取了任务17号!
任务17号!处理完成!!
任务3号!处理完成!!
任务池中还有:3
任务池中还有:3
线程No.1获取了任务19号!
任务19号!处理完成!!
任务15号!处理完成!!
线程No.0获取了任务14号!
任务14号!处理完成!!
任务池中还有:1
线程No.4获取了任务20号!
任务20号!处理完成!!
任务池中还有:1
线程No.3获取了任务18号!
任务18号!处理完成!!
任务池中还有:3
任务池中还有:0
任务池中还有:0
任务池中还有:1
Thread-1 stop pool
Thread-2 stop pool
Thread-3 stop pool
Thread-4 stop pool
Thread-5 stop pool

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值