自定义线程池

一、前言

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

二、自定义线程池

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运行结果

运行结果



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

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