我拿了这段代码:
private Queue<Object> myQueue = new ConcurrentLinkedQueue();
public enqueue(Object obj) {
myQueue.add(obj);
}
@Scheduled(fixedRate=1000)
public void publish() {
final List objsToPublish = Lists.newArrayList();
final int listSize = myQueue.size();
for (int i = 0; i < listSize; i++) {
objsToPublish.add(myQueue.poll());
}
expensiveWriteOperation(objsToPublish);
}
然而,如果在此软件中运行的某些其他操作期间,publish()会取消控制,那么这是一个问题,所以我试图让昂贵的调用异步,如下所示:
private Queue<Object> myQueue = new ConcurrentLinkedQueue();
public enqueue(Object obj) {
myQueue.add(obj);
}
@Scheduled(fixedRate=1000)
public void publish() {
final List objsToPublish = Lists.newArrayList();
final int listSize = myQueue.size();
for (int i = 0; i < listSize; i++) {
objsToPublish.add(myQueue.poll());
}
work(objsToPublish);
}
@ASync
void work(List objsToPublish) {
expensiveWriteOperation(objsToPublish);
}
我关心两件事。
1)这个代码是否有效,即使在任何时候调用enqueue,甚至是mid-work()?
2)我是否以正确的方式从队列中传递数据?
答案 0 :(得分:1)
在您的情况下,work()
方法必须是公共的,并且必须从具有publish()
方法的类外部调用。如果这是Spring,那么您最有可能使用动态代理,在这种情况下,从其他地方调用publish()
后,@Async
方法的work()
注释将不再起作用,因为您已经在内部代理实例。
试试这个:
interface AsyncInternalWrapper {
void work(List objsToPublish);
}
@Service
public class AsyncInternalWrapperImpl implements AsyncInternalWrapper {
@Async
public void work(List objsToPublish) {
expensiveWriteOperation(objsToPublish);
}
}
然后
@Autowired
private AsyncInternalWrapper wrapper;
@Scheduled(fixedRate=1000)
public void publish() {
....
wrapper.work(objsToPublish);
}
另一方面,由于这是一个预定的流程,因此不需要用户交互。那么让publish()
调用返回更快的真正好处是什么?您可能想要考虑这种异步操作提供的优势(如果有的话),而不是在没有好的参数的情况下过度设计。
关于你的问题,请记住,publish()
将由Executor服务在自己的线程中执行,所以你自然就已经在做了#34; async&#34;呼叫。我猜这是使用并发队列的动力。 @Async
会发生的事情是,除了执行publish()