欢迎访问宙启技术站
智能推送

Java函数实现线程池:如何创建和控制线程池?

发布时间:2023-06-25 13:28:01

一、线程池的概念

线程池是一种省略线程创建和销毁时间开销的技术,通过在任务到达时重复利用在池中的线程来提高系统的性能。我们通过以下几个步骤实现Java线程池。

二、创建线程池

我们可以通过Java自带的Executor框架或自己实现线程池,这里我们演示的是自己实现线程池。

定义一个线程池类 MyThreadPool,其中需要有如下成员变量和方法:

1、成员变量:

线程池大小:private int size;

任务队列:private List<Runnable> taskQueue;

线程队列:private List<WorkThread> threads;

2、方法:

执行任务方法:public void execute(Runnable task);

添加任务方法:private synchronized void addTask(Runnable task);

关闭线程池方法:public synchronized void shutdown();

销毁线程池方法:private synchronized void destroy();

其中,线程池大小就是线程池中线程的数量,任务队列是用来保存等待处理的任务的,线程队列则是用来保存工作线程的。

三、创建工作线程

定义一个WorkThread类来表示工作线程,然后让其实现Runnable接口,代码如下:

public class WorkThread implements Runnable {

    private MyThreadPool pool;

    private int threadID;

    public WorkThread(MyThreadPool pool, int threadID) {

        this.pool = pool;

        this.threadID = threadID;

    }

    @Override

    public void run() {

        while (!Thread.currentThread().isInterrupted()) {

            Runnable task = null;

            try {

                task = pool.getTask();

            } catch (InterruptedException e) {

                e.printStackTrace();

                Thread.currentThread().interrupt();

            }

            if (task == null) {

                break;

            }

            task.run();

        }

    }

}

工作线程运行时会不断从任务队列中取出任务并执行,如果没有任务,则线程会稍稍等待,等待有任务时再执行。注意:如果取出任务时被线程池关闭了,线程会停止运行。

四、添加任务

添加任务是指向任务队列中添加任务,当队列中有任务时,工作线程就会取出这个任务执行。

private synchronized void addTask(Runnable task) {

    taskQueue.add(task);

    notifyAll();

}

使用synchronized关键字保证线程安全,在任务队列中添加任务,并唤醒工作线程,通知有新的任务加入。

五、获取任务

从任务队列中取出一个任务让工作线程执行

public synchronized Runnable getTask() throws InterruptedException {

    while (taskQueue.isEmpty()) {

        if (isClosed) {

            return null;

        }

        wait();

    }

    return taskQueue.remove(0);

}

使用synchronized和wait/notifyAll机制实现从任务队列中获取任务,如果队列为空则暂时阻塞等待。

六、执行任务

执行任务即调用Runnable中的run方法。

@Override

public void run() {

    while (!Thread.currentThread().isInterrupted()) {

        Runnable task = null;

        try {

            task = pool.getTask();

        } catch (InterruptedException e) {

            e.printStackTrace();

            Thread.currentThread().interrupt();

        }

        if (task == null) {

            break;

        }

        task.run();

    }

}

七、关闭线程池

关闭线程池有两种方式:

1、调用shutdown方法,让线程池中所有的线程自然结束并关闭。

public synchronized void shutdown() {

    isClosed = true;

    for (WorkThread thread : threads) {

        thread.interrupt();

    }

}

2、调用destroy方法,强制关闭所有线程并销毁线程池。

private synchronized void destroy() {

    for (WorkThread thread : threads) {

        thread.interrupt();

    }

    threads.clear();

    taskQueue.clear();

    isClosed = true;

}

销毁线程池前需要先中断所有的工作线程,清空线程队列和任务队列。

八、总结

Java线程池可以有效地避免不断地创建和销毁线程的开销,提高系统的性能。线程池的实现需要完成以下几个步骤:

1、创建线程池类,定义线程池大小、任务队列、线程队列和任务执行方法等。

2、创建工作线程类,并实现Runnable接口,让工作线程不断地从任务队列中取出任务执行即可。

3、添加任务方法就是向任务队列中添加任务。

4、获取任务方法则是从任务队列中获取任务。

5、执行任务就是调用任务的run方法执行。

6、关闭线程池分正常关闭和强制关闭两种方式。

线程池是Java多线程技术中提高效率和优化性能的重要技术之一,希望以上介绍的内容能对大家有所帮助。