package java.util.concurrent; import java.util.List; import java.util.Collection; public interface ExecutorService extends Executor { //启动一次顺序关闭,执行之前提交的任务,但不接受新任务 void shutdown(); //试图中止全部正在执行的活动任务,暂停处理正在等待的任务,并返回等待执行的任务列表 List<Runnable> shutdownNow(); //若是此执行程序已关闭,则返回 true boolean isShutdown(); //若是关闭后全部任务都已完成,则返回 true boolean isTerminated(); //阻塞当前线程:直到全部任务执行完毕、等待超时或者当前线程中断,才会返回 boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException; //提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future <T> Future<T> submit(Callable<T> task); //提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future Future<?> submit(Runnable task); //提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future <T> Future<T> submit(Runnable task, T result); //执行给定的任务,当全部任务完成时,返回保持任务状态和结果的 Future 列表 <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException; // 执行给定的任务,当全部任务完成或超时期满时(不管哪一个首先发生),返回保持任务状态和结果的 Future 列表 <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit) throws InterruptedException; //执行给定的任务,若是某个任务已成功完成(也就是未抛出异常),则返回其结果 <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException; //执行给定的任务,若是在给定的超时期满前某个任务已成功完成(也就是未抛出异常),则返回其结果 <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }
父接口:html
Executorjava
已知子接口:api
已知实现类:多线程
AbstractExecutorService, ScheduledThreadPoolExecutor, ThreadPoolExecutor闭包
Executors
类提供了用于此包中所提供的执行程序服务的工厂方法。app
提供两个方法来关闭 ExecutorService:ide
shutdown()
方法在终止前容许执行之前提交的任务;没法提交新任务。this
shutdownNow()
方法阻止等待任务启动并试图中止当前正在执行的任务。没有任务在等待执行,而且没法提交新任务,执行中的任务将会收到中断信号。spa
从父接口,继承获得的 execute(Runnable command) 方法,只能执行Runnable类型的线程,并且还不能获得返回值。在ExecutorService 中 submit() 经过返回一个可获取返回值的 Future,不只支持了执行Runnable类型的线程,也支持了Callable的线程执行。
invokeAny() 和 invokeAll() 是批量执行的最经常使用形式,它们执行任务 collection,而后等待至少一个,或所有任务完成(可以使用 ExecutorCompletionService
类来编写这些方法的自定义变体)。
例如,AbstractExecutorService中invokeAny(Collection<? extends Callable<T>> tasks):
public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException { try { return doInvokeAny(tasks, false, 0);//执行上述的私有方法 } catch (TimeoutException cannotHappen) { assert false; return null; } }
其中的doInvokeAny方法:
private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks, boolean timed, long nanos) throws InterruptedException, ExecutionException, TimeoutException { if (tasks == null) throw new NullPointerException(); int ntasks = tasks.size(); if (ntasks == 0) throw new IllegalArgumentException(); List<Future<T>> futures= new ArrayList<Future<T>>(ntasks); // ExecutorCompletionService负责执行任务,后面调用用poll返回第一个执行结果 ExecutorCompletionService<T> ecs = new ExecutorCompletionService<T>(this); // 这里出于效率的考虑,每次提交一个任务以后,就检查一下有没有执行完成的任务 try { ExecutionException ee = null; long lastTime = timed ? System.nanoTime() : 0; Iterator<? extends Callable<T>> it = tasks.iterator(); // 先提交一个任务 futures.add(ecs.submit(it.next())); --ntasks; int active = 1; for (;;) { // 尝试获取有没有执行结果(这个结果是马上返回的) Future<T> f = ecs.poll(); // 没有执行结果 if (f == null) { // 若是还有任务没有被提交执行的,就再提交一个任务 if (ntasks > 0) { --ntasks; futures.add(ecs.submit(it.next())); ++active; } // 没有任务在执行了,并且没有拿到一个成功的结果。 else if (active == 0) break; // 若是设置了超时状况 else if (timed) { // 等待执行结果直到有结果或者超时 f = ecs.poll(nanos, TimeUnit.NANOSECONDS); if (f == null) throw new TimeoutException(); // 这里的更新不可少,由于这个Future多是执行失败的状况,那么还须要再次等待下一个结果,超时的设置仍是须要用到。 long now = System.nanoTime(); nanos -= now - lastTime; lastTime = now; } // 没有设置超时,而且全部任务都被提交了,则一直等到第一个执行结果出来 else f = ecs.take(); } // 有返回结果了,尝试从future中获取结果,若是失败了,那么须要接着等待下一个执行结果 if (f != null) { --active; try { return f.get(); } catch (ExecutionException eex) { ee = eex; } catch (RuntimeException rex) { ee = new ExecutionException(rex); } } } // ExecutorCompletionService执行时发生错误返回了全是null的future if (ee == null) ee = new ExecutionException(); throw ee; } finally { // 尝试取消全部的任务(对于已经完成的任务没有影响) for (Future<T> f : futures) f.cancel(true); } }
当全部的任务被提交后,任务执行返回的Future会被依次添加到一个BlockingQueue中,而后找到第一个执行成功任务的方法就是从BlockingQueue取出第一个元素,这个就是doInvokeAny方法用到的ExecutorCompletionService的基本原理。
void shutdown()
启动一次顺序关闭,执行之前提交的任务,但不接受新任务。若是已经关闭,则调用没有其余做用。
抛出:
SecurityException
- 若是安全管理器存在而且关闭,此 ExecutorService 可能操做某些不容许调用者修改的线程(由于它没有保持 RuntimePermission
("modifyThread")),或者安全管理器的 checkAccess 方法拒绝访问。
List<Runnable> shutdownNow()
试图中止全部正在执行的活动任务,暂停处理正在等待的任务,并返回等待执行的任务列表。
没法保证可以中止正在处理的活动执行任务,可是会尽力尝试。例如,经过 Thread.interrupt()
来取消典型的实现,因此没法响应中断的任务可能将永远没法终止。
返回:
从未开始执行的任务的列表
抛出:
SecurityException
- 若是安全管理器存在而且关闭,此 ExecutorService 可能操做某些不容许调用者修改的线程(由于它没有保持 RuntimePermission
("modifyThread")),或者安全管理器的 checkAccess 方法拒绝访问。
boolean isShutdown()
若是此执行程序已关闭,则返回 true。
返回:
若是此执行程序已关闭,则返回 true
boolean isTerminated()
若是关闭后全部任务都已完成,则返回 true。注意,除非首先调用 shutdown 或 shutdownNow,不然 isTerminated 永不为 true。
返回:
若是关闭后全部任务都已完成,则返回 true
boolean awaitTermination(long timeout,TimeUnit unit) throws InterruptedException
阻塞当前线程:直到全部任务执行完毕、等待超时或者当前线程中断,才会返回。
通常在调用shutdown()方法后调用,用来检测 timeout 时间后线程池是否关闭。
参数:
timeout
- 最长等待时间
unit
- timeout 参数的时间单位
返回:
若是此执行程序终止,则返回 true;若是终止前超时期满,则返回 false
抛出:
InterruptedException
- 若是等待时发生中断
<T> Future<T> submit(Callable<T> task)
提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。该 Future 的 get 方法在成功完成时将会返回该任务的结果。
若是想当即阻塞任务的等待,则可使用 result = exec.submit(aCallable).get(); 形式的构造。
注:Executors
类包括了一组方法,能够转换某些其余常见的相似于闭包的对象,例如,将 PrivilegedAction
转换为 Callable
形式,这样就能够提交它们了。
参数:
task
- 要提交的任务
返回:
表示任务等待完成的 Future
抛出:
RejectedExecutionException
- 若是任务没法安排执行
NullPointerException
- 若是该任务为 null
<T> Future<T> submit(Runnable task, T result)
提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。该 Future 的 get 方法在成功完成时将会返回给定的结果。
参数:
task
- 要提交的任务
result
- 返回的结果
返回:
表示任务等待完成的 Future
抛出:
RejectedExecutionException
- 若是任务没法安排执行
NullPointerException
- 若是该任务为 null
Future<?> submit(Runnable task)
提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。该 Future 的 get 方法在 成功 完成时将会返回 null。
参数:
task
- 要提交的任务
返回:
表示任务等待完成的 Future
抛出:
RejectedExecutionException
- 若是任务没法安排执行
NullPointerException
- 若是该任务为 null
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException
执行给定的任务,当全部任务完成时,返回保持任务状态和结果的 Future 列表。返回列表的全部元素的 Future.isDone()
为 true。注意,能够正常地或经过抛出异常来终止 已完成 任务。若是正在进行此操做时修改了给定的 collection,则此方法的结果是不肯定的。
参数:
tasks
- 任务 collection
返回:
表示任务的 Future 列表,列表顺序与给定任务列表的迭代器所生成的顺序相同,每一个任务都已完成。
抛出:
InterruptedException
- 若是等待时发生中断,在这种状况下取消还没有完成的任务。
NullPointerException
- 若是任务或其任意元素为 null
RejectedExecutionException
- 若是全部任务都没法安排执行
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,long timeout,TimeUnit unit) throws InterruptedException
执行给定的任务,当全部任务完成或超时期满时(不管哪一个首先发生),返回保持任务状态和结果的 Future 列表。返回列表的全部元素的 Future.isDone()
为 true。一旦返回后,即取消还没有完成的任务。注意,能够正常地或经过抛出异常来终止 已完成 任务。若是此操做正在进行时修改了给定的 collection,则此方法的结果是不肯定的。
参数:
tasks
- 任务 collection
timeout
- 最长等待时间
unit
- timeout 参数的时间单位
返回:
表示任务的 Future 列表,列表顺序与给定任务列表的迭代器所生成的顺序相同。若是操做未超时,则已完成全部任务。若是确实超时了,则某些任务还没有完成。
抛出:
InterruptedException
- 若是等待时发生中断,在这种状况下取消还没有完成的任务
NullPointerException
- 若是任务或其任意元素或 unit 为 null
RejectedExecutionException
- 若是全部任务都没法安排执行
<T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException,ExecutionException
执行给定的任务,若是某个任务已成功完成(也就是未抛出异常),则返回其结果。一旦正常或异常返回后,则取消还没有完成的任务。若是此操做正在进行时修改了给定的 collection,则此方法的结果是不肯定的。
参数:
tasks
- 任务 collection
返回:
某个任务返回的结果
抛出:
InterruptedException
- 若是等待时发生中断
NullPointerException
- 若是任务或其任意元素为 null
IllegalArgumentException
- 若是任务为空
ExecutionException
- 若是没有任务成功完成
RejectedExecutionException
- 若是任务没法安排执行
<T> T invokeAny(Collection<? extends Callable<T>> tasks,long timeout,TimeUnit unit) throws InterruptedException,ExecutionException,TimeoutException
执行给定的任务,若是在给定的超时期满前某个任务已成功完成(也就是未抛出异常),则返回其结果。一旦正常或异常返回后,则取消还没有完成的任务。若是此操做正在进行时修改了给定的 collection,则此方法的结果是不肯定的。
参数:
tasks
- 任务 collection
timeout
- 最长等待时间
unit
- timeout 参数的时间单位
返回:
某个任务返回的结果
抛出:
InterruptedException
- 若是等待时发生中断
NullPointerException
- 若是任务或其任意元素或 unit 为 null
TimeoutException
- 若是在全部任务成功完成以前给定的超时期满
ExecutionException
- 若是没有任务成功完成
RejectedExecutionException
- 若是任务没法安排执行
package com.thread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class InvokeAllTest implements Callable<String> { int a = 0; public InvokeAllTest(int a){ this.a=a; } @Override public String call(){ System.out.println("当前值为:" + a); return Integer.toString(a); } public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(3); List<Callable<String>> list = new ArrayList<>(); for (int i = 0; i < 5; i++) { list.add(new InvokeAllTest(i)); } try { List<Future<String>> futures = executorService.invokeAll(list); for (Future<String> future : futures) { System.out.println("返回值:"+future.get()); } } catch (InterruptedException e) {//invokeAll 可能抛出的异常 e.printStackTrace(); } catch (ExecutionException e) {//future.get() 可能抛出的异常 e.printStackTrace(); } executorService.shutdown(); } }
运行结果:
当前值为:0
当前值为:2
当前值为:3
当前值为:4
当前值为:1
返回值:0
返回值:1
返回值:2
返回值:3
返回值:4
若是在call方法中抛出异常了,只有在main方法调用了future.get(),main线程才能捕获到异常:
1.不调用future.get():
package com.thread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class InvokeAllTest implements Callable<String> { int a = 0; public InvokeAllTest(int a) { this.a = a; } @Override public String call(){ System.out.println("当前值为:" + a); if (a == 2) { throw new RuntimeException(); } return Integer.toString(a); } public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(3); List<Callable<String>> list = new ArrayList<>(); for (int i = 0; i < 5; i++) { list.add(new InvokeAllTest(i)); } try { executorService.invokeAll(list); } catch (InterruptedException e) {//invokeAll 可能抛出的异常 e.printStackTrace(); } executorService.shutdown(); } }
运行结果:
当前值为:0
当前值为:1
当前值为:3
当前值为:4
当前值为:2
调用 future.get():
package com.thread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class InvokeAllTest implements Callable<String> { int a = 0; public InvokeAllTest(int a) { this.a = a; } @Override public String call(){ System.out.println("当前值为:" + a); if (a == 2) { throw new RuntimeException(); } return Integer.toString(a); } public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(3); List<Callable<String>> list = new ArrayList<>(); for (int i = 0; i < 5; i++) { list.add(new InvokeAllTest(i)); } try { List<Future<String>> futures = executorService.invokeAll(list); for (Future<String> future : futures) { System.out.println("返回值:" + future.get()); } } catch (InterruptedException e) {//invokeAll 可能抛出的异常 e.printStackTrace(); } catch (ExecutionException e) {//future.get() 可能抛出的异常 e.printStackTrace(); } executorService.shutdown(); } }
运行结果:
当前值为:0
当前值为:2
当前值为:1
当前值为:4
当前值为:3
返回值:0
返回值:1
java.util.concurrent.ExecutionException: java.lang.RuntimeException
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at com.thread.InvokeAllTest.main(InvokeAllTest.java:37)
Caused by: java.lang.RuntimeException
at com.thread.InvokeAllTest.call(InvokeAllTest.java:22)
at com.thread.InvokeAllTest.call(InvokeAllTest.java:11)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
将上述例子:
executorService.invokeAll(list);
修改成:
executorService.invokeAll(list, 15, TimeUnit.SECONDS);
若在call()中有异常抛出,只有在main方法调用了future.get(),main线程才能捕获到异常。
package com.thread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class InvokeAllTest implements Callable<String> { int a = 0; public InvokeAllTest(int a) { this.a = a; } @Override public String call() { System.out.println("当前值为:" + a); return Integer.toString(a); } public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(3); List<Callable<String>> list = new ArrayList<>(); for (int i = 0; i < 5; i++) { list.add(new InvokeAllTest(i)); } try { String value = executorService.invokeAny(list); System.out.println("最后结果值是======:" + value); } catch (InterruptedException e) {//invokeAll 可能抛出的异常 e.printStackTrace(); } catch (ExecutionException e) {//future.get() 可能抛出的异常 e.printStackTrace(); } executorService.shutdown(); } }
运行结果:
当前值为:0
当前值为:2
当前值为:3
当前值为:1
最后结果值是======:0
当前值为:4
invokeAny取得了某一个线程返回的值以后,可是其余线程仍将继续运行,直到运行结束。
若是任意一个任务在call()抛出了异常,而且异常没有在call()中被显示捕获处理,那么控制台将不会打印任何异常信息。
package com.thread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class InvokeAllTest implements Callable<String> { int a = 0; public InvokeAllTest(int a) { this.a = a; } @Override public String call() throws Exception{ if (a>0) { throw new Exception("error"); } System.out.println("当前值为:" + a); return Integer.toString(a); } public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(3); List<Callable<String>> list = new ArrayList<>(); for (int i = 0; i < 5; i++) { list.add(new InvokeAllTest(i)); } try { String value = executorService.invokeAny(list); System.out.println("最后结果值是======:" + value); } catch (InterruptedException e) {//invokeAll 可能抛出的异常 e.printStackTrace(); } catch (ExecutionException e) {//future.get() 可能抛出的异常 e.printStackTrace(); } executorService.shutdown(); } }
运行结果:
当前值为:0
最后结果值是======:0
若全部的任务都发生异常,那么将返回最后一个异常而且输出异常信息,最终在ExecutionException中被捕获:
package com.thread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class InvokeAllTest implements Callable<String> { int a = 0; public InvokeAllTest(int a) { this.a = a; } @Override public String call() throws Exception{ if (a>-1) { throw new Exception("error"); } System.out.println("当前值为:" + a); return Integer.toString(a); } public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(3); List<Callable<String>> list = new ArrayList<>(); for (int i = 0; i < 5; i++) { list.add(new InvokeAllTest(i)); } try { String value = executorService.invokeAny(list); System.out.println("最后结果值是======:" + value); } catch (InterruptedException e) {//invokeAll 可能抛出的异常 e.printStackTrace(); } catch (ExecutionException e) {//future.get() 可能抛出的异常 e.printStackTrace(); } executorService.shutdown(); } }
运行结果:
java.util.concurrent.ExecutionException: java.lang.Exception: error
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at java.util.concurrent.AbstractExecutorService.doInvokeAny(AbstractExecutorService.java:193)
at java.util.concurrent.AbstractExecutorService.invokeAny(AbstractExecutorService.java:215)
at com.thread.InvokeAllTest.main(InvokeAllTest.java:33)
Caused by: java.lang.Exception: error
at com.thread.InvokeAllTest.call(InvokeAllTest.java:20)
at com.thread.InvokeAllTest.call(InvokeAllTest.java:10)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
将上述例子:
executorService.invokeAny(list);
修改成:
executorService.invokeAny(list, 15, TimeUnit.SECONDS);
Executor接口很是单一,就是执行一个Runnable的命令。
public interface Executor { void execute(Runnable command); }
ExecutorService接口扩展了Executor接口,增长状态控制,执行多个任务返回Future。
关于状态控制的方法:
// 发出关闭信号,不会等到现有任务执行完成再返回,可是现有任务仍是会继续执行, // 能够调用awaitTermination等待全部任务执行。再也不接受新的任务。 void shutdown(); // 马上关闭,尝试取消正在执行的任务(不保证会取消成功),返回未被执行的任务 List<Runnable> shutdownNow(); // 是否发出关闭信号 boolean isShutdown(); // 是否全部任务都执行完毕在shutdown以后,也就是若是不调用shutdownNow或者 // shutdown是不可能返回true boolean isTerminated(); // 进行等待直到全部任务完成或者超时 boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
提交单个任务,马上返回一个Future存储任务执行的实时状态
<T> Future<T> submit(Callable<T> task); <T> Future<T> submit(Runnable task, T result); Future<?> submit(Runnable task);
执行多个任务的方法,有两种方式,一种等到全部任务执行完成才返回:
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException; <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException;
另一种是等到有一个任务完成,取消其余未完成的任务,返回执行完成的任务的执行结果:
<T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException; <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
经过上面的代码能够看出ExecutorService能够执行两种类型的任务:Runnable和Callable,而Callable用的更加多。二者区别很简单,前者不会返回执行结果然后者会返回一个执行结果:
public interface Callable<V> { V call() throws Exception; }
接着说说Future,也就是执行任务的返回类型。
Future能够当作是一张发票。好比你送件衣服到洗衣店清洗,他们会开张发票给你,你拿着发票能够去拿回你洗好的衣服或者去洗衣店问衣服是否洗好了等等。
public interface Future<V> { //取消任务,参数mayInterruptIfRunning为true时,若是要取消的任务正在执行, //会把执行这个任务的线程设为中断,为false时,正在执行的任务会被容许执行完成 boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); //获取执行结果,若是任务执行中,会等到任务完成再返回 V get() throws InterruptedException, ExecutionException; V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }
最后看看ScheduledExecutorService接口,该接口是ExecutorService的子接口,增长了定时执行任务的功能:
public interface ScheduledExecutorService extends ExecutorService { public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit); public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit); // 等待必定时间而后开始执行一个任务,每隔period参数设置的时间 // 重复一次,(多线程执行) public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit); // 等待必定时间而后开始执行一个任务,完成后,等待delay参数设置的时间 // 而后在执行一次任务。(单线程执行) public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit); }