Callable 和 Runnable接口的区别:
- (1)Callable规定的方法是call(),而Runnable规定的方法是run().
- (2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。
- (3)call()方法可抛出异常,而run()方法是不能抛出异常的。
- (4)运行Callable任务可拿到一个Future对象, Future表示异步计算的结果。
- 它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。
- 通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。
- Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。
- 实现implements Callable<List<V>> 返回LIst<T>List<Future<T>> 一般配合invokeAll(Collection<? extends Callable<T>> tasks),
- Future.get()方法在执行成功后可以返回结果
- 提交一个任务 Future<T> submit(Callable<T> task);
ExecutorService简介:
ExecutorService是Executor直接的扩展接口,也是最常用的线程池接口,
方法:
1.<T> Future<T> submit(Callable<T> task);提交一个带有返回值的任务(Callable), Future.get()方法返回成功执行后的结果。
2.<T> Future<T> submit(Runnable task, T result);提交一个Runnable任务执行,返回一个Future做为任务task的代理,Future.get()方法在执行成功后可以返回结果。
3.Future<?> submit(Runnable task);提交一个Runnable任务执行,返回一个Future做为任务task的代理,Future.get()方法在执行成功后可以返回结果
4. 方法invokeAny and invokeAll 可以执行一组任务,等待至少一个任务或者多个任务完成(ExecutorCompletionService扩展了这些方法的实现)。
5.void shutdown();发起一个关闭请求,已提交的任务会执行,但不会接受新的任务请求了。 这个方法不会等待已提交的任务全部执行完成,如果你希望这样做,可以使用awaitTermination方法
6.List<Runnable> shutdownNow();这个方法会停掉所有执行中的任务,取消等待中的任务,返回等待执行的任务 的list
方法不会等待执行中的任务停止,如果你希望这样做,可以使用awaitTermination方法
7.boolean isShutdown();如果线程池停止完成返回true
8.boolean isTerminated();如果线程池停止完成返回true ,当所有的任务都停止了,返回true, 注意:只有调用 shutdown 或者 shutdownNow 才返回true
9.<T> T invokeAny(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit) throws InterruptedException,
执行一组任务,在未超时情况下,当成功执行完一个任务(没有抛异常),就返回结果。不论正常返回还是异常结束,未执行的任务都会被取消。
如果在任务执行过程中参数Collection改变了,那么返回结果是不确定的 ExecutionException, TimeoutException;
10.<T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException;
执行一组任务,当成功执行完一个任务(没有抛异常),就返回结果,不论正常返回还是异常结束,未执行的任务都会被取消。
如果在任务执行过程中参数Collection改变了,那么返回结果是不确定的。
11. <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;
执行一组任务,返回一个Future的list,其中的Future持有任务执行完成的结果和状态 对于每一个返回的结果,Future.isDone = true
完成的任务可能正常结束或者异常结束, 如果在任务执行过程中参数Collection改变了,那么返回结果是不确定的。
创建一个
private static ExecutorService executor = new ThreadPoolExecutor(THREAD_CORE_MIN, THREAD_MAX_NUM, 10L, TimeUnit.MINUTES,
new LinkedBlockingQueue<Runnable>(), new ThreadFactory() {
@Override
public Thread newThread(Runnable runnable) {
Thread thread = new Thread(runnable);
thread.setName("线程--" + thread.getId());
return thread;
}
});
public static <T> List<T> doJob(final List<Callable<List<T>>> jobs) {
List<T> result = new ArrayList<T>();
try {
if (!executor.isShutdown()) {
List<Future<List<T>>> results = executor.invokeAll(jobs);
for (Future<List<T>> future : results)
result.addAll(future.get());
}
} catch (InterruptedException e) {
log.error("线程中断异常", e);
} catch (ExecutionException e) {
log.error("线程执行异常", e);
} catch (Exception e) {
log.error("其它错误异常", e);
}
return result;
}
public static void doJob(final Runnable runnable) {
try {
if (!executor.isShutdown()) {
executor.submit(runnable);
}
} catch (Exception e) {
log.error("其它错误异常", e);
}
}