java executorservice的使用_java并发中ExecutorService的使用

java并发中ExecutorService的使用

ExecutorService是java中的一个异步执行的框架,通过使用ExecutorService可以方便的创建多线程执行环境。

本文将会详细的讲解ExecutorService的具体使用。

创建ExecutorService

通常来说有两种方法来创建ExecutorService。

第一种方式是使用Executors中的工厂类方法,例如:

ExecutorService executor = Executors.newFixedThreadPool(10);

复制代码

除了newFixedThreadPool方法之外,Executors还包含了很多创建ExecutorService的方法。

第二种方法是直接创建一个ExecutorService, 因为ExecutorService是一个interface,我们需要实例化ExecutorService的一个实现。

这里我们使用ThreadPoolExecutor来举例:

ExecutorService executorService =

new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue());

复制代码

为ExecutorService分配Tasks

ExecutorService可以执行Runnable和Callable的task。其中Runnable是没有返回值的,而Callable是有返回值的。我们分别看一下两种情况的使用:

7ae0a534ab66d54c43500dfb31cf8bd7.png

将task分配给ExecutorService,可以通过调用xecute(), submit(), invokeAny(), invokeAll()这几个方法来实现。

execute() 返回值是void,他用来提交一个Runnable task。

executorService.execute(runnableTask);

复制代码

submit() 返回值是Future,它可以提交Runnable task, 也可以提交Callable task。 提交Runnable的有两个方法:

Future submit(Runnable task, T result);

Future> submit(Runnable task);

复制代码

第一个方法在返回传入的result。第二个方法返回null。

再看一下callable的使用:

Future future =

executorService.submit(callableTask);

复制代码

invokeAny() 将一个task列表传递给executorService,并返回其中的一个成功返回的结果。

String result = executorService.invokeAny(callableTasks);

复制代码

invokeAll() 将一个task列表传递给executorService,并返回所有成功执行的结果:

List> futures = executorService.invokeAll(callableTasks);

复制代码

关闭ExecutorService

如果ExecutorService中的任务运行完毕之后,ExecutorService不会自动关闭。它会等待接收新的任务。如果需要关闭ExecutorService, 我们需要调用shutdown() 或者 shutdownNow() 方法。

shutdown() 会立即销毁ExecutorService,它会让ExecutorServic停止接收新的任务,并等待现有任务全部执行完毕再销毁。

executorService.shutdown();

复制代码

shutdownNow()并不保证所有的任务都被执行完毕,它会返回一个未执行任务的列表:

List notExecutedTasks = executorService.shutdownNow();

复制代码

oracle推荐的最佳关闭方法是和awaitTermination一起使用:

executorService.shutdown();

try {

if (!executorService.awaitTermination(800, TimeUnit.MILLISECONDS)) {

executorService.shutdownNow();

}

} catch (InterruptedException e) {

executorService.shutdownNow();

}

复制代码

先停止接收任务,然后再等待一定的时间让所有的任务都执行完毕,如果超过了给定的时间,则立刻结束任务。

Future

submit() 和 invokeAll() 都会返回Future对象。之前的文章我们已经详细讲过了Future。 这里就只列举一下怎么使用:

Future future = executorService.submit(callableTask);

String result = null;

try {

result = future.get();

} catch (InterruptedException | ExecutionException e) {

e.printStackTrace();

}

复制代码

ScheduledExecutorService

ScheduledExecutorService为我们提供了定时执行任务的机制。

我们这样创建ScheduledExecutorService:

ScheduledExecutorService executorService

= Executors.newSingleThreadScheduledExecutor();

复制代码

executorService的schedule方法,可以传入Runnable也可以传入Callable:

Future future = executorService.schedule(() -> {

// ...

return "Hello world";

}, 1, TimeUnit.SECONDS);

ScheduledFuture> scheduledFuture = executorService.schedule(() -> {

// ...

}, 1, TimeUnit.SECONDS);

复制代码

还有两个比较相近的方法:

scheduleAtFixedRate( Runnable command, long initialDelay, long period, TimeUnit unit )

scheduleWithFixedDelay( Runnable command, long initialDelay, long delay, TimeUnit unit )

复制代码

两者的区别是前者的period是以任务开始时间来计算的,后者是以任务结束时间来计算。

ExecutorService和 Fork/Join

java 7 引入了Fork/Join框架。 那么两者的区别是什么呢?

ExecutorService可以由用户来自己控制生成的线程,提供了对线程更加细粒度的控制。而Fork/Join则是为了让任务更加快速的执行完毕。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值