我有一个spring @Controller,它有一个请求映射。当请求被发送给它时,它会创建一个延迟的结果,并在一个委托类上运行一个方法。
在控制器中:
@ResponseBody
@RequestMapping(MenuModelCodes.MENU_NAME)
DeferredResult<HttpEntity<?>> getModelCodesWithClass(String target) {
final DeferredResult<HttpEntity<?>> deferredResult = getNewDeferredResult();
delegator.doStuff(target);
return deferredResult;
}委托器中的doStuff方法是@Async注释的-所以它在另一个线程中运行。在这个线程中,将创建一个新的Phaser来跟踪它将创建的子线程。委派线程本身向phaser注册,并触发对"AnotherClass“中的方法的调用,该方法也被@Async注释。也就是说,委托者现在正在派生子代。
委托者:
public class Delegator {
@Async
public Object doStuff(String requestURI) {
Phaser phaser = new Phaser();
phaser.register();
Object result = anotherClass.createThreadDoWork(phaser);
phaser.arriveAndDeregister();
//Wait until phaser is completed
while (!phaser.isTerminated()) {}
return result;
}
}在这里,通过调用委托器中对createThreadDoWork的调用,创建的每个子衍生线程都将自己注册到phaser,做一些工作,然后到达和取消注册。
AnotherClass:
public class AnotherClass {
@Async
public void createThreadDoWork(Phaser phaser) throws Throwable {
phaser.register();
//some kind of logic / rest call etc.
phaser.arriveAndDeregister();
}
}当所有子线程完成时,坐在这段代码前的委托者:
while (!phaser.isTerminated()) {}将继续,则设置其延迟结果,委派线程将结束。
所以这里有个问题:
我希望每个请求都有一个Phaser --也就是说,每当一个请求创建一个新的委派线程时,我都会创建一个新的Phaser()。
如果我收到5个对我的控制器的请求,每个请求都会产生一个委派线程,每个委派都会创建一个新的Phaser,并将其传递给它们的子代。但是,一旦其中一个线程完成其处理并且其特定的Phaser实例终止,其他委派线程就会继续并返回,而不会完成它们的任务。
相位器可以像这样使用吗?我做错了什么吗?我认为这将是一种有用的方式来跟踪子线程的完成并等待它们完成?
谢谢。
发布于 2014-06-18 21:36:00
相位仪可以这样使用吗?
是的,它可以像这样使用,并且通常会作为同步屏障。
我是不是做错了什么?
是。不要这样做
while (!phaser.isTerminated()) {}忙碌的旋转会要了你的命。取而代之的是:
phaser.awaitAdvance();这将迫使您以不同的方式注册。在实际开始运行之前,您必须注册一个线程。
此外,如果你在相位器中,你有多个阶段,那么你将不得不使用相位器重新评估。
我认为这将是一个有用的方式来跟踪子线程的完成并等待它们完成?
如果您确实有许多未知的线程正在创建,那么使用Phaser会很有用。
https://stackoverflow.com/questions/24286777
复制相似问题