• 自己定义开发线程池


    首先要明白线程池的作用,根本作用是维持一定的线程数去执行任务(也会是run方法) 弄明白这一点我们就可以写一个简易的线程池了 

    首先定义自己的线程池接口 ;

    package com.MyThread.Mytest;
    
    import java.util.List;
    
    
    public interface MyIThreadPool {
    //执行任务 在执行任务时请确保任务添加完毕;
    public void execute();
    
    //添加批量任务
    public void addTask(List<Runnable> tasks);
    
    public void addTask(Runnable task);
    
    public void addTask(Runnable[] tasks);

    //中途添加任务 当线程池开启时可以用该方法添加一般不介意使用
    // 个人觉得线程池可以根据线程大小 维护 多个任务队列
    //每个线程池取模 到对应任务队列中获取;当人本线程中没有提供此实现

    public void addSafeTask(List<Runnable> tasks);
    //销毁线程池 建议使用 销毁前会等待任务完成
    public void destory();
    
    //暴露销毁 不建议使用 可能任务没完成就直接退出
    public void froceDestory();
    
    }
    //接着已经开头提到的思想写出自己的简易线程池 ,具体代码如下
    
    package com.MyThread.Mytest;
    
    import java.util.LinkedList;
    import java.util.List;
    
    public class MyIThreadPoolImp implements MyIThreadPool {
    //任务队列
    private List<Runnable> taskqueue = new LinkedList<Runnable>();
    //默认开启线程数量
    private static final int defaultNums = 5;
    private int threadNums;
    //需设置为volatile型,当赋值变化时线程能感知
    private volatile boolean isRunning = true;
    //线程数 不会变 不需要维持线程安全
    Thread[] taskThreads;
    
    private MyIThreadPoolImp() {
    this(5);
    }
    
    private MyIThreadPoolImp(int num) {
    if (num <= 0) {
    threadNums = defaultNums;
    } else {
    threadNums = num;
    }
    taskThreads = new Thread[threadNums];
    for (int i = 0; i < threadNums; i++) {
    Thread thread = new TaskThread();
    thread.setName("TaskThread--" + i);
    taskThreads[i] = thread;
    }
    
    }
    
    public static MyIThreadPool getMyIThreadPool(int num) {
    return new MyIThreadPoolImp(num);
    }
    
    @Override
    public void addSafeTask(List<Runnable> tasks) {
    synchronized (taskqueue) {
    taskqueue.addAll(tasks);
    }
    
    }
    
    //执行任务
    @Override
    public void execute() {
    for (int i = 0; i < threadNums; i++) {
    System.out.println(taskThreads[i].getName()+"开启啦");
    taskThreads[i].start();
    
    }
    }
    
    @Override
    public void addTask(Runnable[] tasks) {
    for (Runnable task : tasks) {
    taskqueue.add(task);
    }
    }
    
    @Override
    public void addTask(Runnable task) {
    taskqueue.add(task);
    }
    
    //批量添加任务
    @Override
    public void addTask(List<Runnable> tasks) {
    taskqueue.addAll(tasks);
    
    }
    
    @Override
    public void destory() {
    while (!taskqueue.isEmpty()) {
    try {
    Thread.sleep(20);
    } catch (Exception e) {
    System.out.println("请等待任务完成");
    e.printStackTrace();
    }
    }
    isRunning = false;
    for (int i = 0; i < threadNums; i++) {
    taskThreads[i] = null;
    }
    
    
    }
    
    
    @Override
    public void froceDestory() {
    isRunning = false;
    for (int i = 0; i < threadNums; i++) {
    taskThreads[i].destroy();
    }
    
    
    }
    
    class TaskThread extends Thread {
    
    Runnable runnable = null;
    
    @Override
    public void run() {
    //当线程池可用 无限循环
    while (isRunning) {
    synchronized (taskqueue) {
    if (!taskqueue.isEmpty() && isRunning) {
    runnable = taskqueue.remove(0);
    } else {
    try {
    //等待20后释放锁锁
    taskqueue.wait(20);
    } catch (Exception e) {
    e.printStackTrace();
    ;
    }
    }
    }
    //记住将runnable置于同步代码块外,否则会导致一个线程占有锁时间过长
    if (runnable != null) {
    runnable.run();
    }
    
    
    }
    }
    
    }
    }
    
    
    //接下来进行测试
    package com.MyThread.Mytest;
    
    public class MyThreadPoolTest {
    
    public static void main(String[] args){
    MyIThreadPool myIThreadPool = MyIThreadPoolImp.getMyIThreadPool(7);
    for(int i =0 ;i<50;i++){
    myIThreadPool.addTask(new MyTask());
    }
    myIThreadPool.execute();
    myIThreadPool.destory();
    
     
    
    }
    
    static class MyTask implements Runnable{
    
    @Override
    public void run() {
    System.out.println(Thread.currentThread().getName()+"处理了");
    }
    }
    
    }

    可以发现我们用7个线程就完成了我们50个任务;当然这只是简单的线程池实现 没有涉及到复杂的变化,要想更深入的立即还得去看JDK源码
     

  • 相关阅读:
    VS code 配置 PySide6的UI开发环境
    Python及PySide6学习网址
    NOIP2021模拟赛10.12 题解
    P2388 阶乘之乘 题解
    P3992 [BJOI2017]开车
    「NOIP2021模拟赛四 B」Polyline 题解
    P7115 [NOIP2020] 移球游戏 题解
    P7114 [NOIP2020] 字符串匹配 题解
    P3391 【模板】文艺平衡树 题解
    致夏天
  • 原文地址:https://www.cnblogs.com/sishahu/p/11067883.html
Copyright © 2020-2023  润新知