Чтобы не получать дважды 1:
public class AtomicSequenceGenerator implements SequenceGenerator {
private AtomicLong value = new AtomicLong(1);
private volatile LocalDate lastDate = LocalDate.now();
@Override
public long getNext() {
LocalDate today = LocalDate.now();
if (!today.equals(lastDate)) {
synchronized(this) {
if (!today.equals(lastDate)) {
lastDate = today;
value.set(1);
}
}
}
return value.getAndIncrement();
}
}
Это немного уродливо, поэтому попробуйте один счетчик:
public class AtomicSequenceGenerator implements SequenceGenerator {
private static long countWithDate(long count, LocalDate date) {
return (((long)date.getDayOfYear()) << (63L-9)) | count;
}
private static long countPart(long datedCount) {
return datedCount & ((1L << (63L-9)) - 1);
}
private static boolean dateChanged(long datedCount, LocalDate date) {
return (int)(datedCount >>> (63L-9)) != date.getDayOfYear();
}
private AtomicLong value = new AtomicLong(countWithDate(1, LocalDate.now()));
@Override
public long getNext() {
long datedCount = value.getAndIncrement();
LocalDate today = LocalDate.now();
if (dateChanged(dateCount, today)) {
long next = countWithDate(1L, today);
if (value.compareAndSet(datedCount+1, next)) {
datedCount = next;
} else {
datedCount = getNext();
}
}
return datedCount;
}
}
При этом используется AtomicLong с указанием днягод упакован в счетчик.
- Один тянет за следующий счетчик.
- Если дата изменилась, то:
- , когда можно установить 1 на следующий день, а затем датьit.
- когда нет, кто-то раньше, возможно, с более ранним счетчиком взял 1, а затем нам нужно снова взять следующий.