public class ThreadSafe implements ITaskCompletionListener {
private final Set<String> taskIds = new HashSet<String>();
private final Set<String> successfulIds = new HashSet<String>();
private final Set<String> cancelledIds = new HashSet<String>();
private final Set<String> errorIds = new HashSet<String>();
public ThreadSafe() {
}
// invoked concurrently
@Override
public void onCancel(String pTaskId) {
remove(pTaskId);
cancelledIds.add(pTaskId);
}
// invoked concurrently
@Override
public void onError(String pTaskId) {
remove(pTaskId);
errorIds.add(pTaskId);
}
// invoked concurrently
@Override
public void onSuccess(String pTaskId) {
remove(pTaskId);
successfulIds.add(pTaskId);
}
private void remove(String pTaskId) {
taskIds.remove(pTaskId);
}
}
public class ThreadSafe implements ITaskCompletionListener { private final Set<String> taskIds = new HashSet<String>(); private
Share
This code is riddled with thread-safety problems.
HashSet is not thread-safe (it is based on the non-threads-safe HashMap – race conditions in which can end up causing infinite loops).
Secondly, there is no atomicity between an ID being in the
taskIdsset and it being added to one of the others, so a task’s existence is ephemeral.Thirdly, the code implicitly assumes that the task state is simply inProgress -> success|error|cancel and that there is no concurrent task execution. If this is not true then the code fails.