【手写线程池实现】

1 手写多线程

1.1 流程梳理:

  1. 创建MyThreadExecutor线程池类
  2. 【定义成员变量】:
	     初始化线程数量;
	     链表阻塞队列;
	     结束线程池标识;
  2. 【创建有参构造方法】
		 初始化线程数量,并调用“线程任务内部类”;
  3. 【创建“线程任务内部类”】
		 用于执行阻塞队列中的任务;
  4. 【创建添加任务方法execute()】;
  5. 【创建销毁线程池方法shutdown()】

代码实现

/**
 * 自定义线程池
 * @author 祁
 */
public class MyThreadExecutor {
    
    

    // 核心线程数
    private volatile int corePoolSize;

    // 任务队列
    private final BlockingQueue<Runnable> workQueue = new LinkedBlockingDeque<>();

    // 结束标识,结束的策略:当flag为false时并且任务全部执行完后再关闭线程池。
    private volatile boolean flag = true;

    // 有参构造创建线程池,并初始化核心线程数
    MyThreadExecutor(int corePoolSize){
    
    
        this.corePoolSize = corePoolSize;
        for (int i = 0; i < corePoolSize; i++) {
    
    
            MyTask myTask = new MyTask();
            myTask.start();
        }
    }

    // 添加任务方法
    public void execute(Runnable runnable) throws InterruptedException {
    
    
        workQueue.put(runnable);
    }

    // 关闭线程池方法
    public void shutdown(){
    
    
        this.flag = false;
    }

    // 内部线程类,用于执行任务
    class MyTask extends Thread{
    
    
        @Override
        public void run() {
    
    
            while (workQueue.size() > 0 || flag){
    
    
                // 获取需要执行的任务
                Runnable poll = workQueue.poll();
                if (poll != null){
    
    
                    try {
    
    
                        Thread.sleep(20);
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace();
                    }
                    poll.run();
                }
            }
        }
    }

}

测试

public static void main(String[] args) throws InterruptedException {
        System.out.println("主线程开始");
		
        // 创建自定义线程池,核心线程数2
        MyThreadExecutor myThreadExecutor = new MyThreadExecutor(2);
        for (int i = 0; i < 5; i++) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            };
            // 将任务添加到线程池
            myThreadExecutor.execute(runnable);
        }
        // 关闭线程池
        myThreadExecutor.shutdown();

        System.out.println("主线程结束");
    }

优化

while (workQueue.size() > 0 || flag)
这段代码非常损耗性能,不管队列有没有任务都会一直循环运行。

解决:

将:Runnable poll = workQueue.poll();
改为:Runnable poll = workQueue.take(); // take()若队列为空,则阻塞线程,直到获取到元素*

猜你喜欢

转载自blog.csdn.net/qq_36881887/article/details/127120148
今日推荐