当我使用Retrofit向服务器发送异步调用时,我将此调用放入列表中。
因此,当呼叫状态发生更改(来自服务器的响应或被用户取消,...)时,我将在列表中添加/删除该呼叫。
进行呼叫且列表中没有先前的呼叫时,将显示进度对话框。当列表中的最后一个呼叫被删除时,它将关闭该对话框。
那么在这种情况下,哪种数据结构将是最佳选择?我看过一些有关java.util.concurrent包的文章。我确定CopyOnWriteArrayList不是一个好选择,因为我需要如此频繁地添加/删除数据,但是那又如何呢?。目前我正在使用LinkedBlockingQueue。
最佳答案
您不仅需要同步数据结构,还需要同步进度对话框实例访问。您可以像这样进行同步:
private Object lock = new Object();
private Set<Call> calls = new HashSet<>();
private ProgressDialog progressDialog;
void addCall(Call call) {
synchronized(lock) {
calls.add(call);
if (calls.size() == 1) {
progressDialog.show();
}
}
}
void removeCall(Call call) {
synchronized(lock) {
calls.remove(call);
if (calls.size() == 0) {
progressDialog.hide();
}
}
}
有关同步here的更多信息。
说到性能,这种锁定应该不是问题。如果遇到性能问题,则需要进行调查,找到瓶颈并进行相应的修改。请记住,每个线程安全的数据结构都有其自身的开销和折衷。
CopyOnWriteArrayList
是一个很好的例子;变异效率极低,但如果您主要执行遍历,则完美。