线程池thread pool,可减少并发线程的数目
1. 调用Executors类中静态方法newCachedThreadPool或newFixedThreadPool
2. 调用submit提交Runnable或Callable对象(记得保存好返回的Future对象)
3. 当不再提交任何任务时,调用shutdown或shutdownNow
shutdown方法启动线程池的关闭序列,被关闭的执行器不在接受新的任务,当所有任务完成后,线程池中的线程死亡。
shutdownNow方法会取消尚未开的的所有任务,并试图中断正在执行的线程
ExecutorService exector=Executors.newCachedThreadPool();
Callable_1 callable1=new Callable_1();
Future<Integer> result=exector.submit(callable1);
exector.shutdown();
ExecutorService exector=Executors.newCachedThreadPool();
Callable_1 callable1=new Callable_1();
FutureTask<Integer> result=new FutureTask<>(callable1);
exector.submit(result);
exector.shutdown();
控制任务组
invokeAny方法提交所有对象到一个Callable对象的集合中,并返回某个已经完成的任务的结果,但是无法确定是那个任务的结果。适用于搜索问题答案情景,只要其中一个任务得到答案,计算就可以停止。
invokeAll方法提交所有对象到一个Callable对象的集合中,并返回一个Future对象的集合,代表所有任务的解决方案。当集合返回时,则所有任务全部完成,而且Future对象的顺序不变。但有时会比较耗时,后者任务必须等待前者任务执行完才会开始。
ExecutorCompletionService完成服务类,提交Callable对象到完成服务,该服务管理Future对象的阻塞队列。当某个任务完成时,有结果就返回,无须等待全部任务完成,但是返回的结果对象是有顺序的
eg1:调用invokeAny方法
package com.lmr.thread;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.Semaphore;
public class ControlTaskGroupTest {
public static void main(String[] args) {
List<Callable<Integer>> callablelist=new ArrayList<>();
List<Future<Integer>> tasklist=new ArrayList<>();
Random rand=new Random();
for(int i=1;i<10;i++){
Callable<Integer> callable=new SumCallable(i, i+10, (rand.nextInt(10)+1)*100);//随机生成线程休息时间数,便于识别线程执行的进度
callablelist.add(callable);
}
ExecutorService executor=Executors.newCachedThreadPool();
try {
System.out.println(executor.invokeAny(callablelist));//返回callablelist中某个已经完成了的任务的结果
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class SumCallable implements Callable<Integer>{
private int start;
private int end;
private int sleeptime;//线程休息时间
private int result;
public SumCallable(int start,int end,int sleeptime) {
// TODO Auto-generated constructor stub
this.start=start;
this.end=end;
this.sleeptime=sleeptime;
}
@Override
public Integer call() throws Exception {
// TODO Auto-generated method stub
result=0;
for(int i=start;i<=end;i++){
result+=i;
Thread.sleep(sleeptime);
}
System.out.println("start: "+start+" end: "+end+" sleeptime: "+sleeptime+" result: "+result);
return result;
}
}
结果:返回最先执行完成的任务的结果
result1:
start: 4 end: 14 sleeptime: 100 result: 99
99
result2:
start: 4 end: 14 sleeptime: 200 result: 99
start: 6 end: 16 sleeptime: 200 result: 121
99
eg2:调用invokeAll方法
public class ControlTaskGroupTest {
public static void main(String[] args) {
List<Callable<Integer>> callablelist=new ArrayList<>();
List<Future<Integer>> tasklist=new ArrayList<>();
Random rand=new Random();
for(int i=1;i<10;i++){
Callable<Integer> callable=new SumCallable(i, i+10, (rand.nextInt(10)+1)*100);//随机生成线程休息时间数,便于识别线程执行的进度
callablelist.add(callable);
}
ExecutorService executor=Executors.newCachedThreadPool();
try {
tasklist=executor.invokeAll(callablelist);//返回一个Future对象的列表,代表所有任务的解决方案,当返回时,所有任务已全部完成,且结果是有序的(但比较耗时,须等待所有任务全部完成)
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(Future<Integer> task:tasklist){
try {
System.out.println(" ---------------- "+task.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
结果:必须等所有任务执行完成,才会获得结果。虽然线程的执行速度不同,但结果是有序的。
start: 2 end: 12 sleeptime: 400 result: 77
start: 8 end: 18 sleeptime: 500 result: 143
start: 5 end: 15 sleeptime: 600 result: 110
start: 9 end: 19 sleeptime: 700 result: 154
start: 3 end: 13 sleeptime: 800 result: 88
start: 6 end: 16 sleeptime: 800 result: 121
start: 7 end: 17 sleeptime: 800 result: 132
start: 1 end: 11 sleeptime: 900 result: 66
start: 4 end: 14 sleeptime: 1000 result: 99
---------------- 66
---------------- 77
---------------- 88
---------------- 99
---------------- 110
---------------- 121
---------------- 132
---------------- 143
---------------- 154
eg3:调用完成服务类
public class ControlTaskGroupTest {
public static void main(String[] args) {
List<Callable<Integer>> callablelist=new ArrayList<>();
Random rand=new Random();
for(int i=1;i<10;i++){
Callable<Integer> callable=new SumCallable(i, i+10, (rand.nextInt(10)+1)*100);//随机生成线程休息时间数,便于识别线程执行的进度
callablelist.add(callable);
}
ExecutorService executor=Executors.newCachedThreadPool();
@SuppressWarnings("rawtypes")
ExecutorCompletionService service=new ExecutorCompletionService(executor);//完成服务执行器,提交任务
for(Callable<Integer> callable:callablelist){
service.submit(callable);
}
for(int i=0;i<callablelist.size();i++){
try {
System.out.println(service.take().get());//当任务完成时,有结果就返回,无须等待全部任务完成,但结果没顺序
//take()取出下一个已完成的结果,若无结果可用则阻塞
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
结果:任务已完成就会返回结果打印
start: 9 end: 19 sleeptime: 200 result: 154
154
start: 8 end: 18 sleeptime: 300 result: 143
start: 5 end: 15 sleeptime: 300 result: 110
143
110
start: 3 end: 13 sleeptime: 400 result: 88
88
start: 7 end: 17 sleeptime: 700 result: 132
start: 6 end: 16 sleeptime: 700 result: 121
132
121
start: 2 end: 12 sleeptime: 900 result: 77
77
start: 4 end: 14 sleeptime: 1000 result: 99
start: 1 end: 11 sleeptime: 1000 result: 66
99
66