execute
execute() 是在Executor接口中定义的,ThreadPoolExecutor继承了AbstractExecutorService抽象类,该抽象类实现了ExecutorService接口(但并没有覆盖execute方法),而ExecutorService接口继承了Executor接口。简而言之就是说ThreadPoolExecutor实现了execute()方法。
- awaitTermination(long timeout, TimeUnit unit)方法
private static void excuteTest1() {
ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
executorService.execute(() -> {
try {
TimeUnit.SECONDS.sleep(10);
} catch (Exception e) {
System.out.println("线程内部中断异常 "+ e);
}
});
executorService.shutdown();
try {
executorService.awaitTermination(2,TimeUnit.SECONDS);
} catch (InterruptedException e) {
System.out.println("awaitTermination InterruptedException异常 "+ e);
} catch (Exception e) {
System.out.println("awaitTermination Exception "+ e);
}
}
总结:awaitTermination最大等待时间,等待线程shutdown(),所以一定要先用shutdown()方法,在等待过程中,可被打断。当awaitTermination的最大等待时间到了,除了继续执行下面代码,不会有其它任何功能。
- execute内的线程异常
private static void excuteTest1() {
ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
executorService.execute(() -> {
try {
TimeUnit.SECONDS.sleep(10);
} catch (Exception e) {
System.out.println("线程内部中断异常 " + e);
}
System.out.println("没有异常线程执行完毕");
});
try {
executorService.execute(() -> {
int i = 2 / 0;
});
} catch (Exception e) {
System.out.println("execute()异常Exception " + e);
}
executorService.shutdown();
}
总结:从结果可以看出,当execute内的线程发生异常时,execute方法是无法捕获的,直接可以在控制台看到异常信息,并且不影响其它线程。
submit
submit方法是ExecutorService接口里面定义的,具体的实现由AbstractExecutorService进行。
submit方法被重载了三次,分别对用三个不同的参数。对api摘录如下:
submit public Future<?> submit(Runnable task)
提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。该 Future 的 get 方法在成功 完成时将会返回null。
submit public Future submit(Runnable task,T result) 提交一个
Runnable 任务用于执行,并返回一个表示该任务的 Future。该 Future 的 get 方法在成功完成时将会返回给定的结果result。
submit public Future submit(Callable task)
提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。该 Future 的 get
方法在成功完成时将会返回该任务的结果。 如果想立即阻塞任务的等待,则可以使用 result =
exec.submit(aCallable).get(); 形式的构造。
注:Executors 类包括了一组方法,可以转换某些其他常见的类似于闭包的对象,例如,将 PrivilegedAction 转换为Callable 形式,这样就可以提交它们了。
- get()
private static void futureTest1() {
ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
System.out.println(System.currentTimeMillis());
Future<String> future = executorService.submit(() -> {
try {
TimeUnit.SECONDS.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
return "sss";
});
System.out.println(System.currentTimeMillis());
try {
final String result = future.get();
System.out.println("得到返回结果"+result);
} catch (InterruptedException e) {
System.err.println("get InterruptedException" + e);
} catch (ExecutionException e) {
System.err.println("get ExecutionException" + e);
} catch (Exception e) {
System.err.println("get Exception" + e);
}
executorService.shutdown();
}
总结:get()方法会一直阻塞,直到拿到返回结果。get()会抛出InterruptedException 和ExecutionException。
- get(long timeout, TimeUnit unit)
private static void futureTest1() {
ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
Future<String> future = executorService.submit(() -> {
try {
TimeUnit.SECONDS.sleep(10);
} catch (Exception e) {
System.out.println("线程内部异常" + e);
}
System.out.println("线程快要返回结果");
return "sss";
});
try {
final String result = future.get(2, TimeUnit.SECONDS);
System.out.println("得到返回结果" + result);
} catch (InterruptedException e) {
System.err.println("get InterruptedException" + e);
} catch (ExecutionException e) {
System.err.println("get ExecutionException" + e);
} catch (TimeoutException e) {
System.err.println("get TimeoutException" + e);
} catch (Exception e) {
System.err.println("get Exception" + e);
}
executorService.shutdown();
}
总结:超时后会抛出超时异常,对线程池中线程无任何影响。
- submit提交的线程发生异常
private static void futureTest1() {
ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
Future<String> future = null;
try {
future = executorService.submit(() -> {
try {
TimeUnit.SECONDS.sleep(10);
} catch (Exception e) {
System.out.println("线程内部异常" + e);
}
int i = 2 / 0;
return "sss";
});
} catch (Exception e) {
System.err.println("submit Exception" + e);
}
try {
final String result = future.get(100, TimeUnit.SECONDS);
System.out.println("得到返回结果" + result);
} catch (InterruptedException e) {
System.err.println("get InterruptedException" + e);
} catch (ExecutionException e) {
System.err.println("get ExecutionException" + e);
} catch (TimeoutException e) {
System.err.println("get TimeoutException" + e);
} catch (Exception e) {
System.err.println("get Exception" + e);
}
executorService.shutdown();
}
总结:异常在会get()的ExecutionException 捕获。
- cancel(true):
private static void futureTest1() {
ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
Future<String> future = null;
try {
future = executorService.submit(() -> {
while (!Thread.currentThread().isInterrupted()){
System.out.println("=++++++=");
}
return "sss";
});
} catch (Exception e) {
System.err.println("submit Exception" + e);
}
try {
TimeUnit.MILLISECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(future.cancel(true));
System.out.println(future.isCancelled());
executorService.shutdown();
}
总结:cancel(true)调用interrupt试图去中断线程。
- isDone()
/**
* Returns {@code true} if this task completed.
*
* Completion may be due to normal termination, an exception, or
* cancellation -- in all of these cases, this method will return
* {@code true}.
*
* @return {@code true} if this task completed
*/
boolean isDone();
execute和submit区别
- 方法execute没有返回值,submit有返回值。
如果不需要返回值,使用execute,效率更高。