我是Java的新手,对并发性来说还是新手。但是,我已经和C#合作了一段时间。它并不重要,但为了举例,我试图从服务器上的表中提取数据。我希望方法等到数据被完全拉出。在C#中,我们有async-await模式,可以像这样使用:
private async Task<List<ToDoItem>> PullItems ()
{
var newRemoteItems = await (from p in remoteTable select p).ToListAsync();
return newRemoteItems;
}
我试图在Java中有类似的效果。 Here是我正在尝试移植的确切代码(查看SynchronizeAsync
方法内部。)!但是,Java Azure SDK使用回调。所以,我有几个选择:
使用wait
和notify
模式。以下代码不起作用,因为我不明白我在做什么。
final List<TEntity> newRemoteItems = new ArrayList<TEntity>();
synchronized( this ) {
remoteTable.where().field("lastSynchronized").gt(currentTimeStamp)
.execute(new TableQueryCallback<TEntity>() {
public void onCompleted(List<TEntity> result,
int count,
Exception exception,
ServiceFilterResponse response) {
if (exception == null) {
newRemoteItems.clear();
for (TEntity item: result) {
newRemoteItems.add(item);
}
}
}
});
}
this.wait();
//DO SOME OTHER STUFF
我的另一个选择是将DO SOME OTHER STUFF
移到回调的if(exception == null)
块内。然而,这将导致我的整个方法逻辑被切成碎片,扰乱连续流动。我真的不喜欢这种方法。
现在,问题是:
建议的方法是什么?我正在完成Oracle的Java并发教程。仍然,无能为力。几乎在我阅读的任何地方,建议使用更高级别的内容,而不是wait
和notify
。
我的wait
和notify
出了什么问题?
我的实现阻止了主线程,这被认为是一种不好的做法。但我还能做些什么呢?我必须等待服务器响应!另外,C#await
是否阻止主线程?这怎么不是坏事?
答案 0 :(得分:1)
将DO SOME OTHER STUFF
置于回调中,或声明semaphore,然后在回调中致电semaphore.release
并致电semaphore.aquire
您想要等待的地方。删除synchronized(this)和this.wait。