Search code examples
javaconcurrencyreplaceatomicconcurrent-collections

ConcurrentSkipListSet and replace remove(key)


I am using ConcurrentSkipListSet, which I fill with 20 keys.

I want to replace these keys continuously. However, ConcurrentSkipListSet doesn't seem to have an atomic replace function.

This is what I am using now:

    ConcurrentSkipListSet<Long> set = new ConcurrentSkipListSet<Long>();
    AtomicLong uniquefier = new AtomicLong(1);    

    public void fillSet() { 
    // fills set with 20 unique keys;
    }
    public void updateSet() {
        Long now = Calendar.getInstance().getTimeInMillis();
        Long oldestKey = set.first();
        if (set.remove(oldestKey)) {
            set.add(makeUnique(now));
        }
    }

    private static final long MULTIPLIER = 1024;

    public Long makeUnique(long in) {
        return (in*MULTIPLIER+uniquefier.getAndSet((uniquefier.incrementAndGet())%(MULTIPLIER/2)));
    }

The goal of this whole operation is to keep the list as long as it is, and only update by replacing. updateSet is called some 100 times per ms.

Now, my question is this: does remove return true if the element itself was present before (and isn't after), or does the method return true only if the call was actually responsible for the removal? I.e.: if multiple threads call remove on the very same key at the very same time, will they /all/ return true, or will only one return true?


Solution

  • set.remove will only return true for the thread that actually caused the object to be removed.

    The idea behind the set's concurrency is that multiple threads can be updating multiple objects. However, each individual object can only be updated by one thread at a time.