use*_*234 8 java multithreading
我在为执行程序创建新线程时感到困惑.我的理解是:对于cachedthreadpool,根据任务的提交创建新线程.对于fixedthreadpool和singlethread,无论提交任务如何,都会提前创建线程.我的理解错了吗?
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new LiftOff());
ExecutorService exec = Executors.newFixedThreadPool(3); // Are the three threads created
// after this line executes?
exec.execute(new LiftOff());
ExecutorService exec = Executors.newSingleThreadExecutor(); // Is the single thread created
// after this line executes?
exec.execute(new LiftOff());
Run Code Online (Sandbox Code Playgroud)
简短的回答是,在您提到的所有情况下,仅当您开始执行任务时才会创建线程,即执行此行后不会创建任何线程,并且仅在执行ExecutorService exec = Executors.newFixedThreadPool(3);此行后才会创建第一个线程。exec.execute(new LiftOff());
为了更好、更全面地理解这一点,正如 @Oliver 建议的那样,您需要浏览 Java 源代码并阅读有关ThreadPoolExecutor 的信息,特别是核心池大小、最大池大小等。如果您想用外行人的话快速理解这一点,请阅读这个好答案。
现在,在我带您了解一些示例代码之前,以下是一些需要理解的要点:
Executors将创建并返回对象ExecutorService(请注意ExecutorService是一个接口)。newCachedThreadPool(),newFixedThreadPool(int nThreads)您将得到一个对象ThreadPoolExecutor(请注意,它ThreadPoolExecutor实现了ExecutorService接口)。Executors.newFixedThreadPool(3);,你只能得到一个对象ThreadPoolExecutor其中设置了所有实例变量,如核心池大小、最大池大小等,在您的情况下,它将设置为 3。execute开始执行任务时才会创建实际的线程submitinvokeAll执行任务时才会创建实际的线程。execute,如果当前池大小小于核心池大小,它将仅创建 1 个新线程,因此这就是您开始创建线程的地方。请参阅下面的示例代码,它将帮助您理解并证明线程仅在您开始执行任务时才创建。为了解释一下,我所做的主要技巧是我使用了对象引用变量ThreadPoolExecutor,以便我可以调用类似的方法getPoolSize()(请注意,它getPoolSize()告诉池中当前存在多少个线程),因为当您使用对象引用变量时ExecutorService您无法调用这些方法(我确信我不需要告诉“为什么”)。
当您运行此示例时,您会注意到:
ThreadPoolExecutor poolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);executeRunnable(poolExecutor);您在池中获得了一个线程。package com.learn.stackoverflow.multithreading;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
/**
*
* @author himanshu.agrawal
*
*/
public class ExecutorServiceNumberOfThreads {
public static void main(String[] args) {
System.out.println("### Testing Executors.newFixedThreadPool()");
testNewFixedThreadPool();
}
private static void testNewFixedThreadPool() {
ThreadPoolExecutor poolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
System.out.println("Pool when no execute() : " + poolExecutor.getPoolSize());
executeRunnable(poolExecutor);
System.out.println("Pool after 1st execute() : " + poolExecutor.getPoolSize());
executeRunnable(poolExecutor);
System.out.println("Pool after 2nd execute() : " + poolExecutor.getPoolSize());
executeRunnable(poolExecutor);
System.out.println("Pool after 3rd execute() : " + poolExecutor.getPoolSize());
executeRunnable(poolExecutor);
System.out.println("Pool after 4th execute() : " + poolExecutor.getPoolSize());
executeRunnable(poolExecutor);
System.out.println("Pool after 5th execute() : " + poolExecutor.getPoolSize());
}
private static void executeRunnable(ThreadPoolExecutor poolExecutor) {
poolExecutor.execute(new Runnable() {
@Override
public void run() {
System.out.println("Running: " + Thread.currentThread().getId() + " | " + new Date());
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
### Testing Executors.newFixedThreadPool()
Pool when no execute() : 0
Pool after 1st execute() : 1
Pool after 2nd execute() : 2
Pool after 3rd execute() : 3
Pool after 4th execute() : 3
Pool after 5th execute() : 3
Running: 10 | Sun Apr 23 19:50:32 IST 2017
Running: 8 | Sun Apr 23 19:50:32 IST 2017
Running: 10 | Sun Apr 23 19:50:32 IST 2017
Running: 9 | Sun Apr 23 19:50:32 IST 2017
Running: 8 | Sun Apr 23 19:50:32 IST 2017
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2550 次 |
| 最近记录: |