prisma-archive/cuid-java

safeCounter() is not thread-safe.

ohyoung79 opened this issue · 0 comments

The current implementation of safeCounter() seems not to be thread-safe. "counter = counter <DISCRETE? counter: 0" and "return counter ++" are likely to work separately. "return counter ++" itself is not thread-safe either. The Orignal program is written in a javascript language that works only in single-thread, it is thread-safe by default. But the java program must be implemented thread-safe. The simplest is to safecounter() synchronized, and if you want to implement lock-free, you'll have to fix it like this:

private static int counter = 0; ==>
private static AtomicInteger counter = new AtomicInteger (0);

private static int safeCounter () {
    counter = counter <DISCRETE_VALUES? counter: 0;
    return counter ++;
} ==>
private static int safeCounter () {
    int oldVal = 0;
    int newVal = 0;
    for (;;) {
        oldVal = counter.get ();
        newVal = oldVal < DISCRETE_VALUES ? oldVal : 0;
        newVal ++;
        if (counter.compareAndSet (oldVal, newVal)) return newVal - 1;
    }
}