Concurrent-Executor Framework

本文详细解析了Callable和Runnable的区别及用途,如何使用FutureTask将Callable任务提交给Thread执行,以及如何获取call()方法的返回值。重点讨论了Executor、ExecutorService和ThreadPoolExecutor等关键接口在并发编程中的角色,以及FutureTask为何不直接实现Runnable和Future接口的原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Executor Framework

 

 

 

Callable  VS  Runnable

1.代表任务,会被线程执行。

不同

1. Callable型的任务能够返回结果或者抛出异常,而Runnable型任务不能

 

//java.util.concurrent 
//Interface Callable<V>
V call() throws Exception

//java.lang 
//Interface Runnable
void run()
 

2. 

 

两个问题

问题1.Thread的target是Runnable类型的,不能直接将Callable型对象作为Thread 的target。

如何将Callable型对象交给Thread?

 写道
Executor接口中的execute(Runnable command)方法的参数也是Runnable型,我们其实也想让Callable型
任务也能够被执行。根据这个需求注意在Executor的子接口ExecutorService中就增加了相关方法submit(Runnable/Callable),submit方法在子类AbstractExecutorService中给出了实现。实现里通过将Runnable/Callable型任务包装成RunnableFuture(继承了Runnable)从而可以交给execute(Runnable command)执行。

问题3:为什么不让FutureTask直接实现Runnable和Future两个接口,而是增加RunnableFuture接口
 

 

问题2.call()方法有返回值——但是call方法并不是直接被调用,而是作为线程执行体被调用。

如何获取call()的返回值?

 

为了解决问题2,JDK1.5中提供了Future接口来代表call()方法的返回值,并提供了一个实现类FutureTask。可以通过

get方法来获得最后执行的结果。

为了解决问题1,让FutureTask实现了Runnable接口,这样可以将 FutureTask交给Thread执行,间接将Callable交给了

Thread。


   

 

 


 

 

FutureTask<V>

 

A cancellable asynchronous computation.

可取消的异步计算 

This class provides a base implementation of Future, with methods to start and cancel a computation, query to see if the computation is complete, and retrieve the result of the computation. 

 

The result can only be retrieved when the computation has completed; the get method will block if the computation has not yet completed. Once the computation has completed, the computation cannot be restarted or cancelled. 

 

A FutureTask can be used to wrap a Callable or Runnable object. Because FutureTask implements Runnable, a FutureTask can be submitted to an Executor for execution. 

 

In addition to serving as a standalone class, this class provides protected functionality that may be useful when creating customized task classes.

Executor接口

 

 

ExecutorService接口

 

 

AbstractExecutorService抽象类

 

 

 

 public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Object> ftask = newTaskFor(task, null);
        execute(ftask);//ftask是Runnable型
        return ftask;//ftask是Future型
    }

    public <T> Future<T> submit(Runnable task, T result) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task, result);
        execute(ftask);
        return ftask;
    }

    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }

protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
        return new FutureTask<T>(runnable, value);
    }

    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        return new FutureTask<T>(callable);
    }

为什么不让FutureTask直接实现Runnable和Future两个接口,而是增加RunnableFuture接口?

注意submit方法有返回值Future,通过这个Future就可以对。。

 

ThreadPoolExecutor类

 

 

 

 

 

ScheduledExecutorService接口

 

 

ScheduledThreadPoolExecutor类

 

 

 

 

 

2025-06-08 11:47:15.380 [start-eval-executor-3] ERROR com.pccw.ihr.base.web.util.SpringAsyncMehodService - Error occurred while invoking exception handler method of async method: startPlan java.lang.reflect.InvocationTargetException: null at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.commons.lang3.reflect.MethodUtils.invokeMethod(MethodUtils.java:230) at org.apache.commons.lang3.reflect.MethodUtils.invokeMethod(MethodUtils.java:256) at org.apache.commons.lang3.reflect.MethodUtils.invokeMethod(MethodUtils.java:148) at com.pccw.ihr.base.web.util.SpringAsyncMehodService.doVoidAsync(SpringAsyncMehodService.java:52) at com.pccw.ihr.base.web.util.SpringAsyncMehodService$$FastClassBySpringCGLIB$$66b60535.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115) 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) Caused by: java.lang.RuntimeException: com.netflix.client.ClientException: Load balancer does not have available server for client: pfmc-settings at org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient.execute(LoadBalancerFeignClient.java:90) at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:108) at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78) at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103) at com.sun.proxy.$Proxy248.selectFormSetByFormId(Unknown Source) at com.pccw.ihr.pfmc.execution.web.service.PfmcStartPlanService.startPlan(PfmcStartPlanService.java:225) at com.pccw.ihr.pfmc.execution.web.service.PfmcStartPlanService$$FastClassBySpringCGLIB$$d6f2fb4c.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) at com.pccw.ihr.pfmc.execution.web.service.PfmcStartPlanService$$EnhancerBySpringCGLIB$$932c812b.startPlan(<generated>) ... 17 common frames omitted Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: pfmc-settings at com.netflix.loadbalancer.LoadBalancerContext.getServerFromLoadBalancer(LoadBalancerContext.java:483) at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:184) at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:180) at rx.Observable.unsafeSubscribe(Observable.java:10327) at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:94) at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:42) at rx.Observable.unsafeSubscribe(Observable.java:10327) at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber$1.call(OperatorRetryWithPredicate.java:127) at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.enqueue(TrampolineScheduler.java:73) at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.schedule(TrampolineScheduler.java:52) at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:79) at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:45) at rx.internal.util.ScalarSynchronousObservable$WeakSingleProducer.request(ScalarSynchronousObservable.java:276) at rx.Subscriber.setProducer(Subscriber.java:209) at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:138) at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:129) at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) at rx.Observable.subscribe(Observable.java:10423) at rx.Observable.subscribe(Observable.java:10390) at rx.observables.BlockingObservable.blockForSingle(BlockingObservable.java:443) at rx.observables.BlockingObservable.single(BlockingObservable.java:340) at com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:112) at org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient.execute(LoadBalancerFeignClient.java:83) ... 31 common frames omitted 2025-06-08 11:47:15.381 [start-eval-executor-3] ERROR c.p.i.b.w.aop.interceptor.IhrAsyncExceptionHandler - Unexpected exception occurred invoking async method: public void com.pccw.ihr.base.web.util.SpringAsyncMehodService.doVoidAsync(java.lang.Object,java.lang.String,java.lang.Object[]) 2025-06-08 11:47:15.381 [start-eval-executor-3] ERROR c.p.i.b.w.aop.interceptor.IhrAsyncExceptionHandler - Params: [com.pccw.ihr.pfmc.execution.web.service.PfmcStartPlanService@cc9ef8d, startPlan, [Ljava.lang.Object;@61d112bd] 2025-06-08 11:47:15.381 [start-eval-executor-3] ERROR c.p.i.b.w.aop.interceptor.IhrAsyncExceptionHandler - Error detail: com.pccw.ihr.base.provider.exception.BusinessException: 异步执行任务出错 at com.pccw.ihr.base.web.util.SpringAsyncMehodService.doVoidAsync(SpringAsyncMehodService.java:55) at com.pccw.ihr.base.web.util.SpringAsyncMehodService$$FastClassBySpringCGLIB$$66b60535.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115) 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)
06-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值