实现线程池(二)最简单的线程池

1,665 阅读1分钟

我们首先实现一个能简单执行任务的线程池,很明显,这样的线程池需要具备两个要素,一个是工作线程,一个是任务队列

//工作线程
private List<Thread> workers;
//任务队列
private final BlockingQueue<Runnable> taskQueue;

工作线程用于执行具体的每一个任务,而任务队列负责接收要执行的任务。

线程池实例化的时候,确定线程池工作线程个数poolSize和最大允许接受任务的个数maxAccept

public MyThreadPool(int poolSize, int maxAccept) {
    workers = new ArrayList<>(poolSize);
    taskQueue = new ArrayBlockingQueue<>(maxAccept);
    this.poolSize = poolSize;
    this.maxAccept = maxAccept;
}

工作线程在线程池的初始化方法中创建和启动

public synchronized void init() {
    if(!inited) {
        for (int i = 0; i < this.poolSize; i++) {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            //从任务队列中取任务,然后执行
                            Runnable runnable = taskQueue.take();
                            runnable.run();
                        } catch (InterruptedException e) {
                        }
                    }
                }
            });
            workers.add(t);
            t.start();
        }
    } else {
        return;
    }
    inited = true;
}

线程池对外提供执行任务的方法

public void execute(Runnable runnable) throws RejectException{
    if(this.taskQueue.size() < maxAccept) {
        this.taskQueue.add(runnable);
    } else {
        //线程池任务队列满了,抛出拒绝异常
        throw new RejectException();
    }
}

实例化线程池,并调用

public static void main(String[] args) {
    MyThreadPool myThreadPool = new MyThreadPool(5,50);
    myThreadPool.init();
    try {
        myThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("任务被执行了");
            }
        });
    } catch (MyThreadPool.RejectException e) {
    }
}

以上,我们实现了一个最简单的线程池

按照我们上一章中提到的,一个完备的线程池除了任务的执行之外,还应该具备以下条件

  • 线程的生命周期管理,主要包括创建和回收
  • 线程池的生命周期,初始化,执行,销毁等

显然,本例子中,并没有完整地体现线程和线程池的生命周期,我们实现的还有缺陷,下一章针对本部分进行完善。