美文网首页
自定义线程池

自定义线程池

作者: M_派森 | 来源:发表于2021-01-24 10:53 被阅读0次

    一、前言

    前一节介绍了线程池基本参数和概念,下面说下如何自定义线程池。

    二、自定义线程池

    1、步骤

    (1)编写任务类(MyTask),实现Rubbalbe接口;

    (2)编写线程类(MyWorker),用于执行任务,需要持有所有任务;

    (3)编写线程池类(MyThreadPool),包含提交任务,执行任务的能力;

    (4)编写测试类(MyTest),创建线程池对象,提交多个任务测试。

    2、具体代码

    2.1MyTask

    package com.threadpoolexecutor.demo01;

    /*

        需求:

            自定义线程练习,这是任务类,需要实现Runnable;

            包含任务编号,每一个任务执行时间设计为0.2

    */

    public class MyTask implements Runnable{

    private int id;

    //由于run方法是重写接口中的方法,因此id这个属性初始化可以利用构造方法完成

        public MyTask(int id) {

    this.id = id;

    }

    @Override

        public void run() {

    String name =Thread.currentThread().getName();

    System.out.println("线程:" +name +"即将执行任务:" +id);

    try {

    Thread.sleep(200);

    }catch (InterruptedException e) {

    e.printStackTrace();

    }

    System.out.println("线程:" +name +"完成了任务:" +id);

    }

    @Override

        public String toString() {

    return "MyTask{" +

    "id=" +id +

    '}';

    }

    }

    MyTask

    2.2MyWorker

    package com.threadpoolexecutor.demo01;

    import java.util.List;

    /*

        需求:

            编写一个线程类,需要继承Thread类,设计一个属性,用于保存线程名字;

            设计一个集合,用于保存所有的任务*/

    public class MyWorker extends Thread{

    //public class MyWorker implements Runnable{

        // 保存线程的名字

        private String name;

    private Listtasks;

    // 利用构造方法,给成员变量赋值

        public MyWorker(String name,List tasks) {

    super(name);

    this.tasks = tasks;

    }

    @Override

        public void run() {

    // 判断集合中是否有任务,只要有,就一直执行

            while (tasks.size() >0){

    Runnable r =tasks.remove(0);

    r.run();

    }

    }

    }

    MyWorker

    2.3MyThreadPool

    package com.threadpoolexecutor.demo01;

    import java.util.Collections;

    import java.util.LinkedList;

    import java.util.List;

    /*

        这是自定义线程池类

        成员变量:        1:任务列表 集合 需要控制线程安全问题        2:当前线程数量        3:核心线程数量        4:最大线程数量        5:任务队列的长度

        成员方法:        1:提交任务:

                将任务添加到集合中,需要判断是否超出了任务总长度        2:执行任务:

                判断当前线程的数量,决定创建核心线程还是非核心线程*/

    public class MyThreadPool {

    // 1:任务队列 集合 需要控制线程安全问题

        private Listtasks =Collections.synchronizedList(new LinkedList<>());

    // 2:当前线程数量

        private int num;

    // 3:核心线程数量

        private int corePoolSize;

    // 4:最大线程数量

        private int maxSize;

    //5:任务队列的长度

        private int workSize;

    public MyThreadPool(int corePoolSize,int maxSize,int workSize) {

    this.corePoolSize = corePoolSize;

    this.maxSize = maxSize;

    this.workSize = workSize;

    }

    // 1:提交任务

        public void submit(Runnable r){

    // 判断当前集合中任务数量,是否超出了最大任务数量

            if (tasks.size() >=workSize){

    System.out.println("任务:" + r +"被抛弃了...");

    }else {

    tasks.add(r);

    // 执行任务

                execTask(r);

    }

    }

    // 2:执行任务

        public void execTask(Runnable r){

    // 判断当前线程池中的线程总数量,是否超出了核心数

            if (num

    new MyWorker("核心线程:" +num,tasks).start();

    //            new Thread(new MyWorker("核心线程:" + num, tasks)).start();

                num ++;

    }else if (num

    new MyWorker("非核心线程:" +num,tasks).start();

    //            new Thread(new MyWorker("非核心线程:" + num, tasks)).start();

                num ++;

    }else {

    System.out.println("任务:" + r +"被缓存了...");

    }

    }

    }

    MyThreadPool

    2.4MyTest

    package com.threadpoolexecutor.demo01;

    public class MyTest {

    public static void main(String[] args) {

    MyThreadPool pool =new MyThreadPool(2,4 ,20);

    for (int i =0; i <30; i++){

    MyTask my =new MyTask(i);

    pool.submit(my);

    }

    }

    }

    MyTest

    2.5运行结果

    运行结果

    参考:网易云课堂-全面深入学习线程池

    相关文章

      网友评论

          本文标题:自定义线程池

          本文链接:https://www.haomeiwen.com/subject/pyxmzktx.html