Java-自定义线程池

ThreadPoolExecutor部分源码

构造方法:

    public ThreadPoolExecutor(int corePoolSize,//核心线程数
                              int maximumPoolSize,//最大线程数
                              long keepAliveTime,//最大空闲时间
                              TimeUnit unit,//时间单位
                              BlockingQueue<Runnable> workQueue//任务队列
                              RejectedExecutionHandler handler//饱和处理机制
                              ) {
    }

线程池设计:

  1. 核心线程数:银行正式员工数量
    例如执行一个任务需要0.1秒,系统百分之八十的时间一秒钟生产100个任务,那么想要在1秒钟处理完所有任务需要十个线程,因此核心线程数是10;
  2. 任务队列:银行大厅座位
    核心线程数/单个任务执行时间*2
  3. 最大线程数:核心线程数加上不得不添加的线程数(临时工)
    最大线程数 = (最大任务数-任务队列长度)*单个任务执行时间(最大任务数:系统每秒生产任务量)
  4. 最大空闲时间:当银行没有办业务的人超过指定时间临时工下班(线程被销毁)
    合理即可
  5. 饱和处理机制:当超过银行所能接待人数启用饱和处理机制

线程池原理:
在这里插入图片描述

自定义线程池——实现步骤

  1. 编写任务类(MyTask)继承Runnable接口
package com.itheima.Demo1;

/*
      需求:
        自定义线程练习,这是任务类需要实现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) {
            throw new RuntimeException(e);
        }
        System.out.println("线程:"+name+"完成了任务:"+id);
    }

    @Override
    public String toString() {
        return "MyTask{" +
                "id=" + id +
                '}';
    }
}

  1. 编写线程类(MyWorker),用于执行任务,需要持有所有任务
package com.itheima.Demo1;


import java.util.List;

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

    private String name;//保存线程的名字
    private List<Runnable> tasks;

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

    @Override
    public void run() {
        //判断集合中是否有任务,只要有,就一直执行任务
        while (tasks.size()>0){
            Runnable r = tasks.remove(0);
            r.run();
        }
    }
}

  1. 编写线程池类(MyThreadPool),包含提交任务,测试任务的能力
package com.itheima.Demo1;

import java.util.*;

/*
    自定义的线程池类:

    成员变量
        1:任务队列   集合
        2:当前线程数量
        3:核心线程数量
        4:最大线程数量
        5:任务队列长度v
    成员方法:
    1:提交任务
         将任务添加到集合中,需要判断是否超出了任务总长度
    2:执行任务
        判断当前线程的数量,决定创建核心线程还是非核心线程
 */
public class MyThreadPool {
    //任务队列
    private List<Runnable> tasks = Collections.synchronizedList(new LinkedList<>());
    //当前线程数量
    private int num;
    //核心线程数量
    private int corePoolSize;
    //最大线程数量
    private int maxSize;
    //任务队列的长度
    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) {
        //判断当前线程池中的线程总数量,是否超i出了核心数
        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. 编写测试类(MyTest)
package com.itheima.Demo1;

public class MyTest {
    public static void main(String[] args) {
        //创建线程池类对象
        MyThreadPool pool = new MyThreadPool(2,4,20);
        //提交多个任务
        for (int i = 0;i<30;i++){
            MyTask myTask = new MyTask(i);
            pool.submit(myTask);
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值