线程池的原理:里面有一些沉睡的线程,当一些任务需要新的线程参与时,就将线程池中的某个线程唤醒,去参与这个任务,任务完成,这个线程继续沉睡。
使用线程池的好处:节省资源,降低CPU开销。假设我们做一个类似Tomcat这样的服务器,如果不使用线程池技术,那么来了一个访问就要开一个线程,如果访问的人数一多,那么瞬间CPU就会忙不过来了。但是如果有了线程池技术,假设就在线程池中放50个线程,那么也就是说同时可以有50个人访问,第51个个人来的话就得等待前50个人中的某个人完成了它的操作,这样子的话能确定的系统的最大化开销,在每个人访问的需要时间不长的情况下(也就是说不需要长时间占用一个线程的情况下)这样的处理方法是不错的。
情景模拟:
假设我有结婚了,来了很多朋友,我得招呼每个朋友,收他们的红包,请他们聊天,请他们就坐....这等等的流程。那如果来了一个我还好应付,假设来了10个,那我一个人就不好应付了。所以我就把招待她们的工作交给了我的伴郎。我请了3个伴郎,让这3个伴郎来完成这些事。
public static void main(String[] args) {
/*
* Executor:执行者
*/
//开一个线程池,请了3个伴郎
ExecutorService threadPool = Executors.newFixedThreadPool(3);
//10个朋友
for (int i = 1; i <= 10; i++) {
final int task = i;
// 线程池中选择空闲的伴郎去执行
threadPool.execute(new Runnable() {
@Override
public void run() {
//每个朋友有10轮的接待任务
for (int i = 1; i <= 10; i++) {
System.out.println("伴郎:"+Thread.currentThread().getName()
+ "接待了朋友:" + task + "进行到了第" + i+"轮接待任务");
}
}
});
}
threadPool.shutdown();
}
好,这就是一个使用线程池的简单的例子
================================================
接下来要说的,就是在上面这个源代码的基础上,说说newFixedThreadPool及newCachedThreadPool的区别,shutdown和shutdownNow的区别。
上面的代码使用的是newFixedThreadPool(3)。意思是创建一个含有三个线程的线程池。
那如果改成newCachedThreadPool()是什么呢?这样字的话就编程开启一个动态的线程池,什么意思呢?也就是说当需要线程池参与任务的时候,如果有等待状态的线程,那么就使用;如果没有就再往线程池中添加一个新的线程去完成这个任务。
上面代码使用的是shutdown用来关闭线程池,那么关闭的条件是什么呐?是线程池完成了所有需要完成的任务(包括已提交但是未完成的)。
那如果改成shutdownNow又是什么情况呢?这样的话,线程池关闭的条件是:当前活动线程(已提交)执行完成后就关闭。