文章目录
一、Java自带线程池:
1.newCachedThreadPool
2.newFixedThreadPool
3.newSingleThreadExecutor
二、看个例子
public class ThreadPoolDemo {
public static void main(String[] args){
ExecutorService newCachedService1 = Executors.newCachedThreadPool();
ExecutorService newFixedService2 = Executors.newFixedThreadPool(10);
ExecutorService newSingleService3 = Executors.newSingleThreadExecutor();
for (int i =1;i<=100;i++){
newCachedService1.execute(new MyTask(i));
}
}
static class MyTask implements Runnable {
int i =0;
public MyTask(int i) {
this.i = i;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"程序员做第"+i+"个项目");
//业务逻辑
try {
Thread.sleep(3000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
1.newCachedService1.execute 运行结果
pool-1-thread-1程序员做第1个项目
pool-1-thread-2程序员做第2个项目
pool-1-thread-3程序员做第3个项目
pool-1-thread-4程序员做第4个项目
pool-1-thread-5程序员做第5个项目
pool-1-thread-6程序员做第6个项目
pool-1-thread-7程序员做第7个项目
pool-1-thread-8程序员做第8个项目
pool-1-thread-9程序员做第9个项目
pool-1-thread-10程序员做第10个项目
pool-1-thread-11程序员做第11个项目
pool-1-thread-12程序员做第12个项目
pool-1-thread-13程序员做第13个项目
pool-1-thread-14程序员做第14个项目
pool-1-thread-15程序员做第15个项目
pool-1-thread-17程序员做第17个项目
pool-1-thread-16程序员做第16个项目
pool-1-thread-18程序员做第18个项目
pool-1-thread-19程序员做第19个项目
pool-1-thread-20程序员做第20个项目
pool-1-thread-21程序员做第21个项目
pool-1-thread-22程序员做第22个项目
pool-1-thread-24程序员做第24个项目
pool-1-thread-23程序员做第23个项目
pool-1-thread-25程序员做第25个项目
pool-1-thread-26程序员做第26个项目
pool-1-thread-27程序员做第27个项目
pool-1-thread-28程序员做第28个项目
pool-1-thread-29程序员做第29个项目
pool-1-thread-30程序员做第30个项目
pool-1-thread-31程序员做第31个项目
pool-1-thread-32程序员做第32个项目
pool-1-thread-33程序员做第33个项目
pool-1-thread-34程序员做第34个项目
pool-1-thread-35程序员做第35个项目
pool-1-thread-36程序员做第36个项目
pool-1-thread-37程序员做第37个项目
pool-1-thread-38程序员做第38个项目
pool-1-thread-39程序员做第39个项目
pool-1-thread-40程序员做第40个项目
pool-1-thread-41程序员做第41个项目
pool-1-thread-42程序员做第42个项目
pool-1-thread-43程序员做第43个项目
pool-1-thread-44程序员做第44个项目
pool-1-thread-45程序员做第45个项目
pool-1-thread-46程序员做第46个项目
pool-1-thread-48程序员做第48个项目
pool-1-thread-47程序员做第47个项目
pool-1-thread-49程序员做第49个项目
pool-1-thread-50程序员做第50个项目
pool-1-thread-51程序员做第51个项目
pool-1-thread-52程序员做第52个项目
pool-1-thread-53程序员做第53个项目
pool-1-thread-54程序员做第54个项目
pool-1-thread-55程序员做第55个项目
pool-1-thread-56程序员做第56个项目
pool-1-thread-57程序员做第57个项目
pool-1-thread-58程序员做第58个项目
pool-1-thread-59程序员做第59个项目
pool-1-thread-60程序员做第60个项目
pool-1-thread-61程序员做第61个项目
pool-1-thread-62程序员做第62个项目
pool-1-thread-63程序员做第63个项目
pool-1-thread-64程序员做第64个项目
pool-1-thread-65程序员做第65个项目
pool-1-thread-67程序员做第67个项目
pool-1-thread-66程序员做第66个项目
pool-1-thread-68程序员做第68个项目
pool-1-thread-69程序员做第69个项目
pool-1-thread-70程序员做第70个项目
pool-1-thread-71程序员做第71个项目
pool-1-thread-72程序员做第72个项目
pool-1-thread-73程序员做第73个项目
pool-1-thread-74程序员做第74个项目
pool-1-thread-75程序员做第75个项目
pool-1-thread-76程序员做第76个项目
pool-1-thread-77程序员做第77个项目
pool-1-thread-78程序员做第78个项目
pool-1-thread-79程序员做第79个项目
pool-1-thread-80程序员做第80个项目
pool-1-thread-81程序员做第81个项目
pool-1-thread-82程序员做第82个项目
pool-1-thread-83程序员做第83个项目
pool-1-thread-84程序员做第84个项目
pool-1-thread-85程序员做第85个项目
pool-1-thread-86程序员做第86个项目
pool-1-thread-87程序员做第87个项目
pool-1-thread-88程序员做第88个项目
pool-1-thread-89程序员做第89个项目
pool-1-thread-90程序员做第90个项目
pool-1-thread-91程序员做第91个项目
pool-1-thread-92程序员做第92个项目
pool-1-thread-93程序员做第93个项目
pool-1-thread-94程序员做第94个项目
pool-1-thread-95程序员做第95个项目
pool-1-thread-96程序员做第96个项目
pool-1-thread-97程序员做第97个项目
pool-1-thread-98程序员做第98个项目
pool-1-thread-99程序员做第99个项目
pool-1-thread-100程序员做第100个项目
2.newFixedService2.execute 执行结果
pool-2-thread-2程序员做第2个项目
pool-2-thread-1程序员做第1个项目
pool-2-thread-3程序员做第3个项目
pool-2-thread-4程序员做第4个项目
pool-2-thread-5程序员做第5个项目
pool-2-thread-6程序员做第6个项目
pool-2-thread-7程序员做第7个项目
pool-2-thread-8程序员做第8个项目
pool-2-thread-9程序员做第9个项目
pool-2-thread-10程序员做第10个项目
pool-2-thread-3程序员做第11个项目
pool-2-thread-7程序员做第12个项目
pool-2-thread-9程序员做第13个项目
pool-2-thread-10程序员做第14个项目
pool-2-thread-2程序员做第16个项目
pool-2-thread-8程序员做第18个项目
pool-2-thread-5程序员做第15个项目
pool-2-thread-4程序员做第19个项目
pool-2-thread-6程序员做第20个项目
pool-2-thread-1程序员做第17个项目
pool-2-thread-10程序员做第21个项目
pool-2-thread-8程序员做第23个项目
pool-2-thread-5程序员做第29个项目
pool-2-thread-3程序员做第25个项目
pool-2-thread-9程序员做第22个项目
pool-2-thread-1程序员做第30个项目
pool-2-thread-4程序员做第28个项目
pool-2-thread-2程序员做第27个项目
pool-2-thread-7程序员做第26个项目
pool-2-thread-6程序员做第24个项目
pool-2-thread-8程序员做第32个项目
pool-2-thread-10程序员做第31个项目
pool-2-thread-3程序员做第33个项目
pool-2-thread-5程序员做第34个项目
pool-2-thread-9程序员做第35个项目
pool-2-thread-1程序员做第36个项目
pool-2-thread-4程序员做第37个项目
pool-2-thread-2程序员做第38个项目
pool-2-thread-7程序员做第39个项目
pool-2-thread-6程序员做第40个项目
pool-2-thread-10程序员做第42个项目
pool-2-thread-8程序员做第41个项目
pool-2-thread-3程序员做第43个项目
pool-2-thread-5程序员做第44个项目
pool-2-thread-9程序员做第45个项目
pool-2-thread-1程序员做第46个项目
pool-2-thread-4程序员做第47个项目
pool-2-thread-7程序员做第49个项目
pool-2-thread-2程序员做第48个项目
pool-2-thread-6程序员做第50个项目
pool-2-thread-3程序员做第51个项目
pool-2-thread-1程序员做第58个项目
pool-2-thread-6程序员做第60个项目
pool-2-thread-5程序员做第57个项目
pool-2-thread-9程序员做第56个项目
pool-2-thread-10程序员做第55个项目
pool-2-thread-4程序员做第53个项目
pool-2-thread-2程序员做第54个项目
pool-2-thread-8程序员做第52个项目
pool-2-thread-7程序员做第59个项目
pool-2-thread-3程序员做第61个项目
pool-2-thread-5程序员做第67个项目
pool-2-thread-10程序员做第69个项目
pool-2-thread-1程序员做第68个项目
pool-2-thread-4程序员做第70个项目
pool-2-thread-7程序员做第66个项目
pool-2-thread-8程序员做第65个项目
pool-2-thread-9程序员做第63个项目
pool-2-thread-6程序员做第62个项目
pool-2-thread-2程序员做第64个项目
pool-2-thread-3程序员做第71个项目
pool-2-thread-1程序员做第77个项目
pool-2-thread-6程序员做第80个项目
pool-2-thread-9程序员做第79个项目
pool-2-thread-7程序员做第78个项目
pool-2-thread-5程序员做第72个项目
pool-2-thread-10程序员做第73个项目
pool-2-thread-2程序员做第75个项目
pool-2-thread-8程序员做第74个项目
pool-2-thread-4程序员做第76个项目
pool-2-thread-7程序员做第81个项目
pool-2-thread-9程序员做第84个项目
pool-2-thread-5程序员做第83个项目
pool-2-thread-8程序员做第89个项目
pool-2-thread-3程序员做第82个项目
pool-2-thread-4程序员做第90个项目
pool-2-thread-2程序员做第88个项目
pool-2-thread-10程序员做第87个项目
pool-2-thread-1程序员做第86个项目
pool-2-thread-6程序员做第85个项目
pool-2-thread-9程序员做第92个项目
pool-2-thread-4程序员做第94个项目
pool-2-thread-10程序员做第95个项目
pool-2-thread-6程序员做第93个项目
pool-2-thread-2程序员做第91个项目
pool-2-thread-7程序员做第100个项目
pool-2-thread-5程序员做第99个项目
pool-2-thread-3程序员做第98个项目
pool-2-thread-8程序员做第97个项目
pool-2-thread-1程序员做第96个项目
3.newSingleService3.execute 执行结果
pool-3-thread-1程序员做第1个项目
pool-3-thread-1程序员做第2个项目
pool-3-thread-1程序员做第3个项目
pool-3-thread-1程序员做第4个项目
pool-3-thread-1程序员做第5个项目
pool-3-thread-1程序员做第6个项目
pool-3-thread-1程序员做第7个项目
pool-3-thread-1程序员做第8个项目
pool-3-thread-1程序员做第9个项目
pool-3-thread-1程序员做第10个项目
pool-3-thread-1程序员做第11个项目
pool-3-thread-1程序员做第12个项目
......
三、分析
1. newCachedThreadPool 在底层实现源码:
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
1.1 比如线程池是一个外包公司
比如线程池是一个外包公司,那么Task是公司要承包的项目,worker是干活的程序员
corePoolSize 为核心员工数量
maximumPoolSize 为非核心元数量
workQueue 为队列,不同的队列可存放的临时任务数不同
因为公司里没有程序员,公司包下项目后,需要临时招聘,所以任务需要先放到队列里,等着分配给哪个程序员,目前有100个任务,现在来了一个任务只能放到队列中,newCachedThreadPool没有核心员工,所以只能招临时工,而SynchronousQueue只能存放一个任务,如果不把这个任务领走是不能再接第二个任务的,所以第一个程序员接走了第一个任务,才能有第二个任务,第二个程序员才能接走第二个任务,才能来第三个任务
从例子的运行结果可以看出,每个项目都分配了一个程序员,一个人只做一个项目
1.2 那如果现在把Thread.sleep(3000L); 注释掉
执行结果:
pool-1-thread-2程序员做第2个项目
pool-1-thread-3程序员做第3个项目
pool-1-thread-1程序员做第1个项目
pool-1-thread-4程序员做第4个项目
pool-1-thread-1程序员做第5个项目
pool-1-thread-4程序员做第8个项目
pool-1-thread-3程序员做第6个项目
pool-1-thread-1程序员做第7个项目
pool-1-thread-2程序员做第9个项目
pool-1-thread-1程序员做第11个项目
pool-1-thread-3程序员做第12个项目
pool-1-thread-5程序员做第10个项目
pool-1-thread-4程序员做第13个项目
pool-1-thread-6程序员做第14个项目
pool-1-thread-4程序员做第15个项目
pool-1-thread-5程序员做第16个项目
pool-1-thread-3程序员做第17个项目
pool-1-thread-1程序员做第18个项目
pool-1-thread-6程序员做第19个项目
pool-1-thread-2程序员做第20个项目
pool-1-thread-7程序员做第21个项目
pool-1-thread-2程序员做第22个项目
pool-1-thread-6程序员做第23个项目
pool-1-thread-1程序员做第24个项目
pool-1-thread-5程序员做第27个项目
pool-1-thread-2程序员做第28个项目
pool-1-thread-4程序员做第29个项目
pool-1-thread-5程序员做第32个项目
pool-1-thread-5程序员做第35个项目
pool-1-thread-8程序员做第30个项目
pool-1-thread-6程序员做第34个项目
pool-1-thread-4程序员做第38个项目
pool-1-thread-9程序员做第36个项目
pool-1-thread-8程序员做第41个项目
pool-1-thread-4程序员做第42个项目
pool-1-thread-10程序员做第39个项目
pool-1-thread-9程序员做第45个项目
pool-1-thread-4程序员做第44个项目
pool-1-thread-8程序员做第46个项目
pool-1-thread-11程序员做第43个项目
pool-1-thread-12程序员做第47个项目
pool-1-thread-11程序员做第52个项目
pool-1-thread-9程序员做第48个项目
pool-1-thread-8程序员做第54个项目
pool-1-thread-13程序员做第51个项目
pool-1-thread-8程序员做第59个项目
pool-1-thread-15程序员做第58个项目
pool-1-thread-13程序员做第62个项目
pool-1-thread-14程序员做第55个项目
pool-1-thread-15程序员做第65个项目
pool-1-thread-11程序员做第57个项目
pool-1-thread-14程序员做第68个项目
pool-1-thread-17程序员做第63个项目
pool-1-thread-15程序员做第67个项目
pool-1-thread-19程序员做第69个项目
pool-1-thread-16程序员做第60个项目
pool-1-thread-14程序员做第75个项目
pool-1-thread-15程序员做第72个项目
pool-1-thread-18程序员做第66个项目
pool-1-thread-17程序员做第74个项目
pool-1-thread-15程序员做第81个项目
pool-1-thread-18程序员做第83个项目
pool-1-thread-17程序员做第84个项目
pool-1-thread-22程序员做第79个项目
pool-1-thread-3程序员做第26个项目
pool-1-thread-14程序员做第77个项目
pool-1-thread-21程序员做第76个项目
pool-1-thread-16程序员做第78个项目
pool-1-thread-26程序员做第90个项目
pool-1-thread-16程序员做第94个项目
pool-1-thread-27程序员做第93个项目
pool-1-thread-20程序员做第71个项目
pool-1-thread-26程序员做第97个项目
pool-1-thread-27程序员做第98个项目
pool-1-thread-21程序员做第95个项目
pool-1-thread-3程序员做第92个项目
pool-1-thread-14程序员做第91个项目
pool-1-thread-18程序员做第89个项目
pool-1-thread-7程序员做第25个项目
pool-1-thread-22程序员做第88个项目
pool-1-thread-17程序员做第87个项目
pool-1-thread-25程序员做第86个项目
pool-1-thread-5程序员做第37个项目
pool-1-thread-1程序员做第33个项目
pool-1-thread-2程序员做第31个项目
pool-1-thread-6程序员做第40个项目
pool-1-thread-4程序员做第49个项目
pool-1-thread-24程序员做第82个项目
pool-1-thread-10程序员做第50个项目
pool-1-thread-15程序员做第85个项目
pool-1-thread-12程序员做第53个项目
pool-1-thread-9程序员做第56个项目
pool-1-thread-8程序员做第61个项目
pool-1-thread-13程序员做第64个项目
pool-1-thread-11程序员做第70个项目
pool-1-thread-23程序员做第80个项目
pool-1-thread-19程序员做第73个项目
pool-1-thread-29程序员做第100个项目
pool-1-thread-16程序员做第99个项目
pool-1-thread-28程序员做第96个项目
结果分析:
以线程2为例,我们可以看出,线程2完成了第2,9,20,22,28,31个项目,这是为什么呢?
因为线程复用!
比如:第一个程序员做了第一个项目,第二个程序员做了第二个项目,现在来了第三个项目,正好第一个程序员完成了第一个项目,公司发现他比较闲,那么就把第三个项目给了他,即线程复用:一个线程接收了多个任务!这样公司有100个项目,就不需要再招聘100个程序员
所以:使用什么线程取决于业务时间的长短!
2.newFixedThreadPool 和 newSingleThreadPool
2.1 newFixedThreadPool:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
有10个核心员工,没有临时员工
任务来了就可以分配给10个核心员工,当第11个任务来了,就只能放到队列中
LinkedBlockingQueue是 无界队列:
这里就放90个任务,10个员工干完后再取10个,这就是为什么运行结果是10个10个的一组
2.2 newSingleThreadPool:
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
newSingleThreadPool 核心员工只有一个人,所有的活都只能他一个人干,其他99个都在队列中,在上一个例子中,newSingleThreadPool执行的很快,因为10万个任务每个1毫秒就执行完了,但第二个例子不同,每个任务需要3s才能执行完.
所以,使用什么线程池需要看项目的执行时间 !
四、总结
好记性不如烂笔头,知道不如做到。
