多线程之5-------线程池
线程池的作用
先举一个现实生活的例子,我要办喜事,为了礼仪,要一个一个接待, 来一个人就说"您好,欢迎您",然后接着跟下一个人说"您好,"
在这里接待一个人 就可以看作是创建一个线程,如图
线程池 的 概念:
首先创建一些线程,它们的集合称为线程池。当服务器接受到一个客户请求后,就从线程池中取出一个空闲的线程为之服务,服务完后不关闭该线程,而是将该线程还回到线程式池中。
说到线程池,就必须提到 Executor 的使用
代码如下:
public class ThreadPoolTest {
// 创建一个有3个线程的线程池(固定的线程池)
//ExecutorService threadPool = Executors.newFixedThreadPool(3);
/**
* 创建缓存线程池, 缓存的线程池就是说当任务来了,程序运行不过来了,就自动增加新的线程
* 程序的线程个数是不定的
*/
ExecutorService threadPool = Executors.newCachedThreadPool();
for(int i=0;i<10;i++){
// 往池子里放10个任务
final int task = i;
threadPool.execute(new Runnable(){
@Override
public void run() {
for(int j=1;j<=10;j++){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("线程: "+Thread.currentThread().getName()
+ " 针对第 " + task+ " 次任务" +" 第 " +j+ " 次循环\n");
}
}
});
}
System.out.println("all of 10 tasks 已经完成!");
threadPool.shutdown();//当任务都做完了,将线程池干掉
//以下为延迟 5 秒炸
/*Executors.newScheduledThreadPool(3).schedule(
new Runnable(){
@Override
public void run() {
System.out.println("bombing...");
}
}, 5, TimeUnit.SECONDS);*/
/**
* 以下以固定频率开始炸
* 先延迟 5 s,以2s为周期
*/
Executors.newScheduledThreadPool(3).scheduleAtFixedRate(
new Runnable(){
@Override
public void run() {
System.out.println("bombing...");
}
}, 5, 2, TimeUnit.SECONDS);
/**
* 以上相对时间,如果要绝对时间
* 这样写date.getTime() - System.currentTimeMillis()
* 比如要早上6点炸,date 就是指早上6点,减去当前时间,就是过了多久就炸
*/
}
}
运行结果:
一 创建线程池
1. 创建固定大小的线程池
2. 创建缓存线程池
3. 创建单一线程池
如何实现线程死掉后重新启动?
解答: 开一个单一线程池,
二 .关闭线程池
shutdown 与 shutdownNow 的比较
三 用线程池启动定时器
1. 调用 ScheduledExecutorService 的schedule 方法,返回的 ScheduleFuture 对象可以取消任务
2. 支持间隔重复任务的定时方式,不直接支持绝对定时方式,需要转换成相对时间方式, 比如 date.getTime() - System.currentTimeMillis()。