基本概念
JDK1.5之后引入了java.util.concurrent包,该包丰富了Java线程及线程池的使用,为解决多线程问题提供了极大方便。
线程池作用
http://blog.csdn.net/it_man/article/details/7193727
每次需要线程的时候就创建一个线程,这样做虽然简单,但面临一个问题:如果并发的线程数量较多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率(频繁创建线程和销毁线程需要时间,内存消耗以及线程过度切换)。
所以如何复用线程?即当线程执行完一个任务后,并不被销毁,而是可以继续执行其他的任务。这就是线程池的意义!
应用场景:
- 单个任务处理的时间比较短
- 需处理的任务的数量大
JDK自带线程池
顶级接口是Executor;严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是ExecutorService。
Executor接口的execute(Runnable)方法用来执行Runnable类型的任务
ExecutorService接口中声明了管理线程的一些方法,比如关闭线程池的shutdown()方法。
Executors类中包含一些静态方法,负责生成各种类型的线程池ExecutorService实例。
几个比较重要的类:
类名 | 描述 |
---|---|
ExecutorService | 真正的线程池接口 |
ThreadPoolExecutor | ExecutorService的默认实现 |
ScheduledExecutorService | 和Timer/TimerTask类似,解决那些需要任务重复执行的问题 |
ScheduledThreadPoolExecutor | 继承ThreadPoolExecutor的ScheduledExecutorService接口实现,周期性任务调度的类实现 |
线程池实例
Executors类,提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService接口。
Executors类中生成ExecutorService实例的几种静态方法:
Executors类的静态方法 | 创建的ExecutorService线程池类型 |
---|---|
newCachedThreadPool() | 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程 |
newFixedThreadPool() | 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待 |
newScheduledThreadPool() | 创建一个定长线程池,支持定时及周期性任务执行 |
newSingleThreadExecutor() | 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行 |
1. newCachedThreadPool
package com.xianggen.thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
* @author xianggen
* @2016年8月25日 下午3:25:20
*/
public class TestNewCachedThreadPool {
public static void main(String[] args) {
ExecutorService cachedThreadPool=Executors.newCachedThreadPool();
for(int i=0;i<10;i++){
final int index=i;
try{
Thread.sleep(index*1000);
}catch(InterruptedException e){
e.printStackTrace();
}
//将线程放入池中进行执行
//当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。
cachedThreadPool.execute(new Runnable(){
public void run(){
System.out.println(index);
}
});
}
}
}
2. newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
package com.xianggen.thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
* @author xianggen
* @2016年8月25日 下午3:46:09
*/
public class TestNewFixedThreadPool {
public static void main(String[] args) {
//线程池大小为3;
//定长线程池的大小最好根据系统资源进行设置。如Runtime.getRuntime().availableProcessors()
ExecutorService fixedThreadPool=Executors.newFixedThreadPool(3);
for(int i=0;i<10;i++){
final int index=i;
fixedThreadPool.execute(new Runnable(){
public void run(){
try{
//每个任务输出index后sleep 2秒,所以每两秒打印3个数字。
System.out.println(index);
Thread.sleep(2000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
});
}
}
}
3. newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
//表示延迟3秒执行
scheduledThreadPool.schedule(myThread, 3, TimeUnit.SECONDS);
//延迟1秒后每3秒执行一次
scheduledThreadPool.scheduleAtFixedRate(myThread, 1, 3, TimeUnit.SECONDS);
4. newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
singleThreadExecutor.execute(myThread);