java es线程池_【java并发编程实战】第六章:线程池

1.线程池

众所周知创建大量线程时代价是非常大的: - 线程的生命周期开销非常大:创建需要时间,导致延迟处理请求,jvm需要分配空间。 - 资源消耗:线程需要占用空间,如果线程数大于可用的处理器数量,那么线程就会闲置,这给Gc造成压力。线程在竞争cpu的时候也会造成性能开销,所以线程不是越多越好,使用不当并不会增加运行效率。 - 稳定性:使用不当会造成内存溢出。

继而就引申出线程池。

1.1线程池的创建

Executors框架:静态方法创建

newCachedThreadPool:创建可变线程数的线程池。有空闲的时候会回收。

newFixedThreadPool:创建固定线程数的线程池。

newScheduledThreadPool:创建固定数量线程池,以延时、定时的方式执行。

newSingleThreadExecutor:创建单线程线程池。

Executors框架:

生命周期:运行->关闭->已终止 > Executor扩展了ExecutorSerivice接口。提供了平缓关闭接口的方法。调用shutdown方法后会拒绝新增任务,进入关闭状态。等待所有任务处理完进入已终止。showdownNow会立刻进入已终止。调用awaitTermination会立刻调用shutdown等待关闭后返回同步关闭状态。

6d5f861c7c604ea59389a114e01c9338.png

2.callable和future

future异步返回线程计算结果。callable可以以泛型的形式显示定义返回异步返回类型。 下面介绍一个例子:

public class MyCallable implements Callable {

@Override

public String call() throws Exception {

Thread.sleep(1000L);

//return the thread name executing this callable task

return Thread.currentThread().getName();

}

public static void main(String args[]){

//Get ExecutorService from Executors utility class, thread pool size is 10

ExecutorService executor = Executors.newFixedThreadPool(10);

//create a list to hold the Future object associated with Callable

Queue> list = new LinkedBlockingQueue<>();

//Create MyCallable instance

Callable callable = new MyCallable();

for(int i=0; i< 100; i++){

//submit Callable tasks to be executed by thread pool

Future future = executor.submit(callable);

//add Future to the list, we can get return value using Future

list.add(future);

}

while (true) {

Future fut = list.poll();

try {

if (fut.isDone()) {

//print the return value of Future, notice the output delay in console

// because Future.get() waits for task to get completed

System.out.println(new Date()+ "::"+fut.get());

} else {

list.add(fut);

}

} catch (InterruptedException | ExecutionException | CancellationException e ) {

e.printStackTrace();

}

}

}

}

其中,当任务执行完成,调用get会返回Exception。如果么有完成,那么进入阻塞状态直至返回。如果执行过程中抛出异常,Executors会封装成ExecutionException重新抛出,通过getCause获取原始异常。如果任务被取消,就会抛出CancellationException。

3.completionService

轮询的方式太低效,可以考虑completionService

public class MyCallable implements Callable {

@Override

public String call() throws Exception {

Thread.sleep(1000L);

return Thread.currentThread().getName();

}

public static void main(String args[]){

//

ExecutorService executor = Executors.newFixedThreadPool(10);

ExecutorCompletionService stringExecutorCompletionService = new ExecutorCompletionService<>(executor);

Queue> list = new LinkedBlockingQueue<>();

Callable callable = new MyCallable();

for(int i=0; i< 100; i++){

Future future = stringExecutorCompletionService.submit(callable);

list.add(future);

}

while (true) {

try {

Future take = stringExecutorCompletionService.take();

String s = take.get();

System.out.println(s);

} catch (InterruptedException | ExecutionException e) {

e.printStackTrace();

}

}

}

}

// 待补充分析源码。

4.为线程的返回值设置时限。

Future.class

0382b5ea0086350732041429bb1f3fb6.png 如果get超过等待时间讲抛出timeoutexception

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值