package jakiro.sequence.seq; import jakiro.sequence.SequenceException; import jakiro.sequence.dao.SequenceDao; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class DefaultSequence implements Sequence { protected final Lock lock = new ReentrantLock(); private SequenceDao sequenceDao; public SequenceDao getSequenceDao() { return sequenceDao; } public void setSequenceDao(SequenceDao sequenceDao) { this.sequenceDao = sequenceDao; } private String keyName; public String getKeyName() { return keyName; } public void setKeyName(String keyName) { this.keyName = keyName; } protected volatile SequenceRange currentRange; public long nextValue(String kn, int index, int total) throws SequenceException { kn = (kn == null ? keyName : kn); if (currentRange == null) { lock.lock(); try { if (currentRange == null) { currentRange = sequenceDao.nextRange(kn, index, total); } } finally { lock.unlock(); } } long value = currentRange.getAndIncrement(); if (value == -1) { lock.lock(); try { for (;;) { if (currentRange.isOver()) { currentRange = sequenceDao.nextRange(kn, index, total); } value = currentRange.getAndIncrement(); if (value == -1) { continue; } break; } } finally { lock.unlock(); } } if (value < 0) { throw new SequenceException("Sequence value overflow, value = " + value); } return value; } }