private ExecutorService executor1 = Executors.newFixedThreadPool(5);
for(int i=0;i<10;i++)
executor1.execute(some runnable command);
有谁可以解释上述两个陈述中究竟发生了什么?在哪个语句中创建了一个新线程?创建了多少个新线程?
答案 0 :(得分:1)
创建新的固定线程池时会创建线程,但这些线程还没有执行任何操作。他们站在旁边等着执行任务。
当您告诉固定的线程池执行程序执行Runnable
时,该runnable将被发送到其中一个空闲线程,然后它将开始与程序执行并行运行。当Runnable
终止时,完成的线程再次处于待机状态并等待进一步的工作。
当你告诉执行者服务在池中的所有线程都忙时执行runnables时,那些runnables将被放入队列并在runnable完成时执行。
答案 1 :(得分:0)
执行程序消息将执行您在另一个线程中指定的runnable。
private ExecutorService executor1 = Executors.newFixedThreadPool(5);
表示您正在其线程池中创建一个包含5个线程的执行程序对象。因此,当有请求进入时,它将使用这五个中的一个线程并执行请求。
for(int i=0;i<10;i++)
executor1.execute(some runnable command);
此声明表示您正在为执行程序服务提供10个任务。由于执行程序有5个线程,它将开始执行前五个任务,后续任务将被安排执行。也就是说,当前五个任务完成后,该线程将返回线程池,然后分配给执行第6个任务。
例如:
线程1:执行任务1
线程2:执行任务2
线程3:执行任务3
主题4:执行任务4
线程5:执行任务5
假设线程3完成其工作,然后:
线程3:执行任务6
然后假设线程1完成其工作:
线程1:执行任务7
依旧......
直到所有预定的任务完成。由于线程池大小为5,因此一次最多只能完成5个并行任务。希望我的解释能帮到你。
答案 2 :(得分:0)
查看ThreadPoolExecutor.execute()方法的源代码。
方法1:检查ThreadPool大小和池运行状态。
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
if (runState == RUNNING && workQueue.offer(command)) {
if (runState != RUNNING || poolSize == 0)
ensureQueuedTaskHandled(command);
}
else if (!addIfUnderMaximumPoolSize(command))
reject(command); // is shutdown or saturated
}
}
方法2:
private void ensureQueuedTaskHandled(Runnable command) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
boolean reject = false;
Thread t = null;
try {
int state = runState;
if (state != RUNNING && workQueue.remove(command))
reject = true;
else if (state < STOP &&
poolSize < Math.max(corePoolSize, 1) &&
!workQueue.isEmpty())
t = addThread(null);
} finally {
mainLock.unlock();
}
if (reject)
reject(command);
else if (t != null)
t.start();
}
方法3:使用runnalbe.run()方法创建和启动线程。
private Thread addThread(Runnable firstTask) {
Worker w = new Worker(firstTask);
Thread t = threadFactory.newThread(w);
if (t != null) {
w.thread = t;
workers.add(w);
int nt = ++poolSize;
if (nt > largestPoolSize)
largestPoolSize = nt;
}
return t;
}