实现一个简单的线程池需要考虑以下几个关键点:
以下是一个简单的线程池实现,支持任务的提交和执行:
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class SimpleThreadPool {
// 线程池中的线程数量
private final int poolSize;
// 任务队列
private final Queue<Runnable> taskQueue = new LinkedList<>();
// 线程池中的工作线程
private final WorkerThread[] threads;
// 锁和条件变量
private final ReentrantLock lock = new ReentrantLock();
private final Condition notEmpty = lock.newCondition();
// 线程池是否关闭
private volatile boolean isShutdown = false;
public SimpleThreadPool(int poolSize) {
this.poolSize = poolSize;
this.threads = new WorkerThread[poolSize];
// 创建并启动工作线程
for (int i = 0; i < poolSize; i++) {
threads[i] = new WorkerThread();
threads[i].start();
}
}
// 提交任务到线程池
public void submit(Runnable task) {
if (isShutdown) {
throw new IllegalStateException("Thread pool is shut down.");
}
lock.lock();
try {
taskQueue.add(task);
notEmpty.signal(); // 唤醒一个等待的工作线程
} finally {
lock.unlock();
}
}
// 关闭线程池
public void shutdown() {
lock.lock();
try {
isShutdown = true;
notEmpty.signalAll(); // 唤醒所有等待的工作线程
} finally {
lock.unlock();
}
}
// 工作线程类
private class WorkerThread extends Thread {
@Override
public void run() {
while (true) {
Runnable task = null;
lock.lock();
try {
// 检查线程池是否关闭
if (isShutdown && taskQueue.isEmpty()) {
return; // 如果线程池关闭且任务队列为空,则退出线程
}
// 如果任务队列为空,则等待
while (taskQueue.isEmpty() && !isShutdown) {
notEmpty.await();
}
// 如果线程池未关闭,则取出一个任务
if (!isShutdown) {
task = taskQueue.poll();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
// 执行任务
if (task != null) {
task.run();
}
}
}
}
}
任务队列:
LinkedList
作为任务队列,存储待执行的任务。ReentrantLock
和Condition
来实现线程安全的任务队列操作。
工作线程:
Thread
类,重写run
方法。notEmpty.await()
进入等待状态,直到有任务被提交。
任务提交:
submit
方法,允许外部提交任务到线程池。notEmpty.signal()
唤醒一个等待的工作线程。
线程池关闭:
shutdown
方法,关闭线程池。isShutdown
标志为true
,并调用notEmpty.signalAll()
唤醒所有等待的工作线程。isShutdown
为true
且任务队列为空时,退出运行。
public class Main {
public static void main(String[] args) {
SimpleThreadPool threadPool = new SimpleThreadPool(4); // 创建一个包含4个工作线程的线程池
// 提交任务
for (int i = 0; i < 10; i++) {
int taskNumber = i;
threadPool.submit(() -> {
System.out.println("Executing task: " + taskNumber + " on thread: " + Thread.currentThread().getName());
try {
Thread.sleep(1000); // 模拟任务执行时间
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
// 关闭线程池
threadPool.shutdown();
}
}
Executing task: 0 on thread: WorkerThread-0
Executing task: 1 on thread: WorkerThread-1
Executing task: 2 on thread: WorkerThread-2
Executing task: 3 on thread: WorkerThread-3
Executing task: 4 on thread: WorkerThread-0
Executing task: 5 on thread: WorkerThread-1
Executing task: 6 on thread: WorkerThread-2
Executing task: 7 on thread: WorkerThread-3
Executing task: 8 on thread: WorkerThread-0
Executing task: 9 on thread: WorkerThread-1
ReentrantLock
和Condition
确保任务队列操作的线程安全。
这个简单的线程池实现可以作为学习和理解线程池工作原理的基础。在实际项目中,建议使用Java标准库中的java.util.concurrent
包提供的线程池实现(如ExecutorService
),它们经过了严格的测试和优化,功能更加完善。