Java函数实现线程池:如何创建和控制线程池?
一、线程池的概念
线程池是一种省略线程创建和销毁时间开销的技术,通过在任务到达时重复利用在池中的线程来提高系统的性能。我们通过以下几个步骤实现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多线程技术中提高效率和优化性能的重要技术之一,希望以上介绍的内容能对大家有所帮助。
