当我使用Retrofit向服务器发送异步调用时,我将此调用放入列表中。
因此,当呼叫状态发生变化(来自服务器的响应或用户取消,......)时,我在列表中添加/删除呼叫。
当进行呼叫并且列表中不存在先前呼叫时,它显示进度对话框。当在列表中删除最后一个调用时,它会关闭该对话框。
那么在这种情况下,哪种数据结构将是最佳选择?我已经看过一些关于java.util.concurrent包的帖子。我确定CopyOnWriteArrayList不是一个好选择,因为我需要频繁地添加/删除数据,但其他呢......目前我使用的是LinkedBlockingQueue。
答案 0 :(得分:2)
也许尝试使用Collections.newSetFromMap(new ConcurrentHashMap()),因为它可以让你在O(1)附近添加和删除。
答案 1 :(得分:1)
您不仅需要同步数据结构,还需要同步进度对话框实例访问权限。您可以这样同步:
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
就是一个很好的例子;在突变方面效率极低,但如果你主要进行遍历则是完美的。