关于和new thread的区别,不做延伸。
好处:(copy网上的解释)
a. 重用存在的线程,减少对象创建、消亡的开销,性能佳。
b. 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。
c. 提供定时执行、定期执行、单线程、并发数控制等功能。
四种ExcutorService:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
1、newCachedThreadPool理解为一个无限线程池大小的线程池
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int index = i;
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(index);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
可能会有疑问,既然无限线程池的大小,为何不直接new 一个Thread,使用线程池可以回收空闲的线程,当没有可回收的情况时,则新建线程,因此相对于每次都直接new 一个Thread,减少了新建线程的耗时,增加了资源可利用性。
(私下测试过单纯Sysout的10万个线程,时间是2400ms:460ms)
2、newFixedThreadPool 定长的线程池,线程数量超出时,等待。这个很好理解,不做解释。
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
final int index = i;
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(index);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
3、newSingleThreadExecutor 单线程的线程池,类似于newFixedThreadPool(1),常用场景是用于一些任务按照指定顺序执行。
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(index);
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
4、newScheduledThreadPool,定长线程池,支持定时及周期性任务。
scheduleAtFixedRate(task,delay,period,timeUtil):从上一个任务开始执行后,period周期后执行下一个任务,但是如果上一个任务未执行完,需要等上一个任务先执行完
scheduleWithFixedDelay(task,dalay,period,timeUtil):从上一个任务结束后,p'eriod周期执行下一个任务
schedule(task,period,timeUtil):period秒后开始执行
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3);
executorService.schedule(new Runnable() {
@Override
public void run() {
System.out.println("yes");
}
}, 3, TimeUnit.SECONDS);
// 从上一个任务开始执行后,3秒后执行下一个任务,但是如果上一个任务未执行完,需要等上一个任务先执行完
executorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("Atfixed");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 1, 3, TimeUnit.SECONDS);
// 从上一个任务执行结束后,3秒后开始执行
executorService.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
System.out.println("fixed");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 1, 3, TimeUnit.SECONDS);
是不是觉得newScheduledThreadPool 和Timer有点像,从jdk1.5之后,建议使用newScheduledThreadPool取代Timer使用,因为他们功能类似,但是稳定性等方面要高于timer