我在创建自己的自定义线程池执行器时遇到了一个问题。我正在尝试在不使用任何执行器服务库的情况下实现相同的目的,以便为 java 面试做准备。我可以在下面的服务中编写代码。
import java.util.LinkedList;
import java.util.Queue;
class Worker extends Thread {
private final Queue<Runnable> taskQueue;
private volatile boolean isStopped = false;
public Worker(Queue<Runnable> taskQueue) {
this.taskQueue = taskQueue;
}
public void run() {
while (!isStopped) {
Runnable task = null;
synchronized (taskQueue) {
while (taskQueue.isEmpty() && !isStopped) {
try {
taskQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (!taskQueue.isEmpty()) {
task = taskQueue.poll();
}
}
if (task != null) {
task.run();
}
if(isStopped)
return;
}
}
public void stopThread() {
isStopped = true;
interrupt(); // Interrupt the thread if it's waiting
}
}
public class CustomThreadPool {
private final int poolSize;
private final Queue<Runnable> taskQueue;
private final Worker[] workers;
public CustomThreadPool(int poolSize) {
this.poolSize = poolSize;
taskQueue = new LinkedList<>();
workers = new Worker[poolSize];
for (int i = 0; i < poolSize; i++) {
workers[i] = new Worker(taskQueue);
workers[i].start();
}
}
public void execute(Runnable task) {
synchronized (taskQueue) {
taskQueue.offer(task);
taskQueue.notifyAll(); // Notify all waiting threads to start executing the task
}
}
public void shutdown() {
for (Worker worker : workers) {
worker.stopThread();
}
}
public static void main(String[] args) {
CustomThreadPool threadPool = new CustomThreadPool(3);
// Submit tasks to the thread pool
for (int i = 1; i <= 5; i++) {
int num = i;
threadPool.execute(() -> {
int result = calculateFactorial(num);
System.out.println("Factorial of " + num + " is " + result + " - Thread: " + Thread.currentThread().getName());
});
}
// Shutdown the thread pool
threadPool.shutdown();
}
private static int calculateFactorial(int n) {
int factorial = 1;
for (int i = 1; i <= n; i++) {
factorial *= i;
}
return factorial;
}
}
下面是上面代码的输出。
Factorial of 1 is 1 - Thread: Thread-0
Factorial of 2 is 2 - Thread: Thread-1
Factorial of 3 is 6 - Thread: Thread-2
这里的问题是我向执行器提交了 5 个任务,我也可以在任务队列中看到相同的任务,但只有 3/5 任务正在执行,因为线程池大小保持为 3。我希望这 3 个线程以某种方式运行这 5 个任务。我需要帮助来理解我做错了什么以及如何强制相同的 3 个线程执行队列中的所有预配任务。
threadPool.shutdown()
调用会杀死所有正在运行的线程,即使它们有待处理的工作。
尝试这样做:
将以下方法添加到您的 CustomThreadPool 中:
public void join() throws InterruptedException {
for (Worker worker : workers) {
worker.join();
}
}
然后,而不是
threadPool.shutdown();
使用
try {
threadPool.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
join()
将等待所有工作线程完成其任务然后返回。