【发布时间】:2020-07-23 18:49:42
【问题描述】:
我正在编写一个服务类,它应该有两种模式:同步和异步。
public class ProcessorImpl implements IProcessor {
private final MyRepo repo;
private final Jobrunner runner;
private final boolean isAsync;
private ExecutorService executorService;
@ProcessorImpl
public ProcessorImpl(final MyRepo repo,
final Jobrunner runner) {
this(repo, runner, false);
}
public ProcessorImpl(final MyRepo repo,
final Jobrunner runner,
final boolean isAsync) {
this.repo = repo;
this.runner = runner;
this.isAsync = isAsync;
}
@PostConstruct
public void init() {
if (isAsync) {
executorService = new ThreadPoolExecutor(1,1,60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(50));
} else {
executorService = new ThreadPoolExecutor(1,1,60, TimeUnit.SECONDS, new SynchronousQueue<>());
}
}
@Override
public Response doAction(final Request request, final String id) {
if (isAsync) {
//submit task and return incomplete response with id
} else {
//submit task and get result and return response that is returned by Callable
}
}
}
切换由isAsync 标志驱动。
当同步时,我希望能够提交任务,从任务提交中获取完成的响应并使用它来构建Response 以返回。对于这种模式,我使用的是SynchronousQueue。
当异步模式开启时,只需提交任务并立即返回,响应不完整。对于这种模式,我使用LinkedBlockingQueue来等待队列中的任务。
关于同步模式,我有两个问题:
-
如何获取结果并以同步方式给出响应?我不确定如何在这里使用
Future。 -
如果线程正在处理任务时另一个命令任务进来怎么办?会被拒绝吗?如何避免被拒绝?
对于一些代码示例的任何帮助将不胜感激。
谢谢
【问题讨论】:
-
你不怕
RejectedExecutionException和new ThreadPoolExecutor(1,1,60, TimeUnit.SECONDS, new SynchronousQueue<>())吗? -
@akuzminykh 实际上我的第二个问题是关于如何在命令来得快于处理速度时避免这种情况。这些
doAction都是由Rest调用请求/响应发起的,有些想要完整的结果,有些可以不完整,稍后再查询。 -
你可以例如使用this 构造函数并给它
ThreadPoolExecutor.CallerRunsPolicy,它只会让调用者执行任务。还有更多。你甚至可以自己实现一个。 -
好的,看看一个例子就好了。如果在这个主线程中我正在做
Future. get()调用等待第一个命令的结果,有什么问题吗? -
我不会使用 isAsync 标志。我会做2个不同的课程。 SyncProcessorImpl 的 doAction 方法返回 Future
,ASyncProcessorImpl 的 doAction 方法返回 Response 并直接进行所有计算,无需线程池。
标签: java spring multithreading concurrency thread-safety