线程池就像任何ExecutorServices一样,我们定义了一个大小为3的新FixedPool。现在我有大约10000个可运行任务的队列。
为了执行上述过程,我有以下疑问:
为了执行上述过程,执行器是否只会让队列中的3个线程同时运行?
该线程池将携带3个线程,这3个线程将负责执行所有10000个任务。如果是正确的,则单个线程如何运行不同的可运行任务,因为最终这些任务本身也是线程,并且在运行任何作业/任务的中间,您可以将新的责任分配给池线程。
线程池就像任何ExecutorServices一样,我们定义了一个大小为3的新FixedPool。现在我有大约10000个可运行任务的队列。
为了执行上述过程,我有以下疑问:
为了执行上述过程,执行器是否只会让队列中的3个线程同时运行?
该线程池将携带3个线程,这3个线程将负责执行所有10000个任务。如果是正确的,则单个线程如何运行不同的可运行任务,因为最终这些任务本身也是线程,并且在运行任何作业/任务的中间,您可以将新的责任分配给池线程。
如果您使用的是Executors.newFixedThreadPool(3)
,则线程池中最多只会有3个线程。
这10,000个任务并不是Threads
,它们只是简单的Runnables
。必须通过Thread#start
启动一个Thread
来实际创建一个系统线程。任务(Runnable
的实例)被放置在BlockingQueue
中。线程池中的线程将轮询BlockingQueue
以获取要运行的任务。当它们完成任务时,它们返回队列以获取另一个任务。如果添加了更多任务,则根据该队列实现的规则将它们插入到BlockingQueue
中。对于大多数队列,这是先进先出,但PriorityQueue
实际上使用Comparator
或自然排序来按顺序插入任务。
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
@SuppressWarnings("all")
public class ThreadPool {
private BlockingQueue taskQueue = null;
private List<PoolThread> threads = new ArrayList<PoolThread>();
private boolean isStopped = false;
public ThreadPool(int noOfThreads, int maxNoOfTasks) {
taskQueue = new LinkedBlockingQueue(maxNoOfTasks);
for(int i=0; i<noOfThreads; i++) {
threads.add(new PoolThread(taskQueue));
}
for(PoolThread thread : threads) {
thread.start();
}
}
public synchronized void execute(Runnable task) {
if(this.isStopped)
throw new IllegalStateException("ThreadPool is stopped");
this.taskQueue.offer(task);
}
public synchronized void stop() {
this.isStopped = true;
for(PoolThread thread : threads) {
thread.stopMe();
}
}
}
@SuppressWarnings("all")
class PoolThread extends Thread {
private BlockingQueue taskQueue = null;
private boolean isStopped = false;
public PoolThread(BlockingQueue queue) {
taskQueue = queue;
}
public void run() {
while(!isStopped()) {
try {
Runnable runnable = (Runnable) taskQueue.poll();
runnable.run();
} catch(Exception e) {
//log or otherwise report exception, //but keep pool thread alive.
}
}
}
public synchronized void stopMe() {
isStopped = true;
this.interrupt();
//break pool thread out of dequeue() call.
}
public synchronized boolean isStopped() {
return isStopped;
}
}