Tura
Tura

Reputation: 1336

I need a thread-safe data structure. What should I use?

When I send an asynchronous call to the server using Retrofit, I put this call to the list.

So when the state of the call changes(response from the server or canceled by the user, ...), I add/remove the call in the list.

When the call is made and no prior call exists in the list, It shows progress Dialog. When the last call is removed in the list, It dismisses the dialog.

So in this situation, which data structure will be the best choice? I've seen some posts about java.util.concurrent package. I'm sure that CopyOnWriteArrayList is not a good choice because I need to add/remove data so frequently but what about else.. currently I'm using LinkedBlockingQueue.

Upvotes: 1

Views: 824

Answers (2)

Geoffrey Marizy
Geoffrey Marizy

Reputation: 5521

You need to synchronize not only the data structure but the progress dialog instance access. You could synchronize like this:

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();
        }
    }
}

More informations on synchronization here.

Speaking about performance, such locking should not be a problem. If you experience performance troubles, you will need to investigate, find the bottleneck and modify accordingly. Bear in mind that every thread-safe data structure come with it's own overhead and trade-offs. CopyOnWriteArrayList is the perfect example; extremely inefficient on mutations, but perfect if you perform mostly traversals.

Upvotes: 1

Guts
Guts

Reputation: 768

Maybe try Collections.newSetFromMap(new ConcurrentHashMap()) as it gives you near O(1) add and remove.

Upvotes: 2

Related Questions