Executor:
public interface Executor {
void execute(Runnable command);
}
一、Executor:一个接口,其定义了一个接收Runnable对象的方法execute(Runnable command),该方法接收一个Runable实例,它用来执行一个任务,任务即一个实现了Runnable接口的类,一般来说,Runnable任务开辟在新线程中的使用方法为:new Thread(new RunnableTask())).start();但在Executor中,可以使用Executor而不用显示地创建线程:executor.execute(new RunnableTask()); // 异步执行
二、ExecutorService:是一个比Executor使用更广泛的子类接口,其提供了生命周期管理的方法,返回 Future 对象,以及可跟踪一个或多个异步任务执行状况返回Future的方法;
- 调用ExecutorService的shutdown()方法来平滑地关闭 ExecutorService,调用该方法后,将导致ExecutorService停止接受任何新的任务且等待已经提交的任务执行完成(已经提交的任务会分两类:一类是已经在执行的,另一类是还没有开始执行的),当所有已经提交的任务执行完毕后将会关闭ExecutorService。因此我们一般用该接口来实现和管理多线程。
- 通过 ExecutorService.submit() 方法返回的 Future 对象,可以调用 isDone() 方法查询Future是否已经完成。当任务完成时,它具有一个结果,你可以调用get()方法来获取该结果。你也可以不用isDone()进行检查就直接调用get()获取结果,在这种情况下,get() 将阻塞,直至结果准备就绪,还可以取消任务的执行。Future 提供了 cancel() 方法用来取消执行 pending 中的任务。
三、Executors类: 主要用于提供线程池相关的操作,提供了一系列工厂方法用于创建线程池,返回的线程池都实现了ExecutorService接口。
- public static ExecutorService newFiexedThreadPool(int Threads) :创建固定数目线程的线程池。
- public static ExecutorService newCachedThreadPool():创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果没有可用的线程,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。
- public static ExecutorService newSingleThreadExecutor():创建一个单线程化的Executor。
- public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) :创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。
Executor执行Callable任务
public class CallableDemo {
public static void main(String[] args) {
ExecutorService executorService= Executors.newCachedThreadPool();
List<Future<String>> resultList=new ArrayList<Future<String>>();
//创建10个任务并执行
for(int i=0;i<10;i++){
//使用ExecutorService执行Callable类型的任务,并将结果保存在future变量中
Future<String> future=executorService.submit(new TaskWithResult(i));
resultList.add(future);
}
for(Future<String> fs:resultList ){
try {
while(!fs.isDone());//没有完成无限循环
System.out.println(fs.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
//启动一次顺序关闭,执行以前提交的任务,但是不接受新任务
executorService.shutdown();
}
}
}
}
class TaskWithResult implements Callable{
private int id;
public TaskWithResult(int id) {
this.id = id;
}
@Override
public String call() throws Exception {
System.out.println("call()方法被调用了:"+Thread.currentThread().getName());
return "call()方法被自动调用了,任务返回结果是:"+id+",线程"+Thread.currentThread().getName();
}
}
参考地址:https://blog.csdn.net/weixin_40304387/article/details/80508236