import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DedupingQueue<E> implements QueueWrapper<E> {
private static final Logger LOGGER = LoggerFactory.getLogger(DedupingQueue.class);
private final Map<E, Future<E>> itemsBeingWorkedOn = new ConcurrentHashMap<>();
private final AsyncWorker<E> asyncWorker; //contains async method backed by a thread pool
public DedupingQueue(AsyncWorker<E> asyncWorker) {
this.asyncWorker = asyncWorker;
}
@Override
public Future<E> submit(E e) {
if (!itemsBeingWorkedOn.containsKey(e)) {
itemsBeingWorkedOn.put(e, asyncWorker.executeWorkAsync(e, this));
} else {
LOGGER.debug("Rejected [{}] as it's already being worked on", e);
}
return itemsBeingWorkedOn.get(e);
}
@Override
public void complete(E e) {
LOGGER.debug("Completed [{}]", e);
itemsBeingWorkedOn.remove(e);
}
@Override
public void rejectAndRetry(E e) {
itemsBeingWorkedOn.putIfAbsent(e, asyncWorker.executeWorkAsync(e, this));
}
}
私は上記のコードのスレッド安全性を推論するいくつかの困難を抱えています。ConcurrentHashMapを使用したキューのスレッド安全性
私はマップがスレッドセーフなので、complete
とrejectAndretry
は完全にスレッドセーフであると考えます。しかし、submit
については、AsyncWorker
それ自体はスレッドセーフではありません。また、どのようにして(ConcurrentHashMapの組み込み保証を使用して)を使用せずに、スレッドを最も効率的な方法で安全にすることができますか?
スレッドの安全性は、どのような動作が期待されるかによって異なります。既存のキーを上書きしたり同じ値を返さない場合は、 'submit()'はスレッドセーフです。 – m0skit0