目前,Java提供了7个线程池给我们使用,各有各的特点。
1. newCachedThreadPool:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
2. newFixedThreadPool:创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
3. newScheduledThreadPool:创建一个定长线程池,支持定时及周期性任务执行。
4. newSingleThreadExecutor:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
5. newSingleThreadScheduledExcutor:创建一个单例线程池,定期或延时执行任务。
6. newWorkStealingPool:创建持有足够线程的线程池来支持给定的并行级别,并通过使用多个队列,减少竞争,它需要传一个并行级别的参数,如果不传,则被设定为默认的CPU数量。
7. ForkJoinPool:支持大任务分解成小任务的线程池,这是Java8新增线程池,通常配合ForkJoinTask接口的子类RecursiveAction或RecursiveTask使用。
newCachedThreadPool 会根据任务来临的需要决定是否创建新的线程,也就是如果来了新任务又没有空闲线程,它就会新建一个线程,下面用代码可以理解这个事情。
public static void main(String []ags) throws Exception{
ExecutorService service=Executors.newCachedThreadPool();
int count=10;
for(int i=0;ifinal int temp=i;
service.execute(new Runnable() {
@Override
public void run() {
// TODO 自动生成的方法存根
System.out.println("当前线程:"+Thread.currentThread()+" temp为:"+temp);
}
});
//不注释,只会产生一个线程,一直重用该线程。注释后有10个线程执行
Thread.sleep(1000);
}
}
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
public static void main(String []ags) throws Exception{
ExecutorService service=Executors.newFixedThreadPool(3);
int count=10;
for(int i=0;ifinal int temp=i;
service.execute(new Runnable() {
@Override
public void run() {
// TODO 自动生成的方法存根
System.out.println("当前线程:"+Thread.currentThread()+" temp为:"+temp);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
});
}
}
创建一个定长线程池,支持定时及周期性任务执行。
public static void main(String []ags) throws Exception{
ScheduledExecutorService service=Executors.newScheduledThreadPool(3);
int count=10;
for(int i=0;ifinal int temp=i;
service.schedule(new Runnable() {
@Override
public void run() {
// TODO 自动生成的方法存根
System.out.println("当前线程:"+Thread.currentThread()+" temp为:"+temp);
}
}, 2, TimeUnit.SECONDS);//延迟2秒后执行
}
}
public static void main(String []ags) throws Exception{
ScheduledExecutorService service=Executors.newScheduledThreadPool(3);
int count=10;
//for(int i=0;i
final int temp=count;
service.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
// TODO 自动生成的方法存根
System.out.println("当前线程:"+Thread.currentThread()+" temp为:"+temp);
}
}, 1, 3, TimeUnit.SECONDS);//初始延迟1秒后执行,之后每隔3秒执行一次
// }
}
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
public static void main(String []ags) throws Exception{
ExecutorService service=Executors.newSingleThreadExecutor();
for(int i=0;i<10;++i){
final int temp=i;
//按顺序执行
service.execute(new Runnable() {
@Override
public void run() {
// TODO 自动生成的方法存根
System.out.println("当前线程:"+Thread.currentThread()+" temp为:"+temp);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
});
}
}
创建持有足够线程的线程池来支持给定的并行级别,并通过使用多个队列,减少竞争,它需要传一个并行级别的参数,如果不传,则被设定为默认的CPU数量。
public static void main(String []ags) throws Exception{
ExecutorService service=Executors.newWorkStealingPool();//默认CPU数量
for(int i=0;i<10;++i){
final int temp=i;
service.execute(new Runnable() {
@Override
public void run() {
// TODO 自动生成的方法存根
System.out.println("当前线程:"+Thread.currentThread()+" temp为:"+temp);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
});
}
Thread.sleep(100000);//不设置没有结果输出
}
ForkJoinPool是一种支持任务分解的线程池,当提交给他的任务“过大”,他就会按照预先定义的规则将大任务分解成小任务,多线程并发执
行。
一般要配合可分解任务接口ForkJoinTask来使用,ForkJoinTask有两个实现它的抽象类:RecursiveAction和RecursiveTask,其区别是前者没有返回值,后者有返回值。
public static class Task extends RecursiveAction{
private static final long serialVersionUID = 1L;
//定义一个分解任务的阈值——10,即一个任务最多承担10个工作量
final static int TOP=10;
//任务量
int taskNum=0;
Task(int Num){
this.taskNum=Num;
}
@Override
protected void compute() { //必须定义的方法,定义如何分解任务
if(taskNum<=TOP){
System.out.println(Thread.currentThread()+"承担了"+taskNum+"份工作");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
//随机解成两个任务
Random m=new Random();
int x=m.nextInt(TOP);
Task left=new Task(x);
Task right=new Task(taskNum-x);
left.fork();
right.fork();
}
}
}
public static void main(String []ags) throws Exception{
ForkJoinPool pool=new ForkJoinPool();//使用默认CPU数为最大线程数,使用默认线程Factory
pool.execute(new Task(50));
pool.awaitTermination(20, TimeUnit.SECONDS);//等待20s
pool.shutdown();
}
参看博客:
http://blog.csdn.net/a369414641/article/details/48350795
http://blog.csdn.net/a369414641/article/details/48342253
http://blog.csdn.net/u011479540/article/details/51867886