自定义线程池实现

思想:

一种多线程处理的形式,处理过程中可以将任务添加到队列中。

优势:

1.线程与任务分离,提升线程重用性;

2.控制线程并发数量,降低服务器压力,统一管理

3.提升系统相应速度

思路:

1.需要一个任务类MyTask,实现Runnale接口,处理业务;

2.需要一个线程类MyWork,继承Thread类;

3.自定义的线程池类MyThreadPool,统一管理线程与任务;

代码:

/**
 * 需求:
 *  自定义线程池练习,这是任务类,需要实现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+"}";
    }
}

/**
 * 需求:
 *  编写一个线程类,需要继承Thread类。设计一属性,用于保存线程的名字;
 *   设计一个集合,用于保存所有的任务;
 */
public class MyWorker extends Thread{

    private String name;

    private List tasks;

    //利用构造方法,给成员变量赋值
    public MyWorker(String name, List tasks){
        this.name= name;
        this.tasks = tasks;
    }

    @Override
    public void run(){
        //判断集合中是否有任务,只要有,就一直执行任务
        while(tasks.size()>0){
            Runnable remove = tasks.remove(0);
            remove.run();
        }
    }
}
/**
 * 这是自定义的线程池类;
 *  成员变量:
 *      1:任务队列  集合  需要控制线程安全问题
 *      2:当前线程数量
 *      3:核心线程数量
 *      4:最大线程数量
 *      5:任务队列的长度
 *  成员方法:
 *      1:提交任务:将任务添加到集合中,需要判断是否超出了任务总长度
 *      2:执行任务:判断当前线程的数量,决定创建核心线程还是非核心线程
 *
 */
public class MyThreadPool {
    //1:任务队列  集合  需要控制线程安全问题
    private List tasks = 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;
    }

    public void submit(Runnable r){
        //判断当前集合中任务的数量,是否超出了最大任务数量
        if(tasks.size() >= workSize){
            System.out.println("任务:"+r+"被丢弃了。。。");
        }else {
            tasks.add(r);
            //执行任务
            execTask(r);
        }
    }

    private void execTask(Runnable r) {
        //判断当前线程池中的线程总数量是否超出了核心数
        if(num < corePoolSize){
            new MyWorker("核心线程:"+num,tasks).start();
            num++;
        }else if(num < maxSize){
            new MyWorker("非核心线程:"+num,tasks).start();
            num++;
        }else {
            System.out.println("任务:"+r+"被缓存了。。。");
        }
    }
}

测试:

/**
 * 测试类
 *  1:创建线程池类对象
 *  2:提交多个任务
 */
public class MyTest {

    public static void main(String[] args) {
        MyThreadPool myThreadPool = new MyThreadPool(2, 4, 20);
        for (int i = 0; i <10 ; i++) {
            Mytask mytask = new Mytask(i);
            myThreadPool.submit(mytask);
        }
    }
}

结果:

image.png

分析:

1:新建一个任务将其提交到线程池中,若满足添加条件则添加到线程池的任务队列中。并且调用执行方法;

2:执行方法判断当前的池中线程总数是否超出,若没有则创建自定义线程,传入任务队列并调用start()方法执行线程;

3:最后自定义线程会从任务列表中取任务调用run()方法执行,至此自定义线程池初步实现;

你可能感兴趣的:(自定义线程池实现)