下面的类实现包含两个字段。达到
AtomicInteger
值后,主序列编号预计将重置为零。每当发生这种情况时,应将max=9999
增加一个。目标是确保在高度并发服务中返回给呼叫者的独特测序ID。
resetCount
我想在这里理解几点:
提供实例变量
public class SequenceGenerator {
private static final SequenceGenerator GENERATOR = new SequenceGenerator();
private final AtomicInteger sequence = new AtomicInteger(0);
private final AtomicInteger resetCount = new AtomicInteger(0);
private SequenceGenerator() {}
public static SequenceGenerator getInstance() {
return GENERATOR;
}
/**
* This method a unique sequenceId that follow this format
* [ResetCount-SequenceNumber]. The SequenceNumber range is [0000,9999]
* and every time the max value 9999 exceeds, it will reset back to zero
* and the ResetCount value will increase by one.
*
* @return a unique sequenceId in literal format
*/
public String generateSequenceId() {
while (true) {
int local = sequence.getAndIncrement();
if (local <= 9999) {
//Do some work and return a unique sequence number literal
return resetCount+"-"+local;
} else {
//Reset after the sequence exceeds 4 digits
//Only a thread with variable local=10000 should
//reset sequence back to zero(0)
if(local == 10000){
sequence.set(0);
resetCount.incrementAndGet();
}
}
}
}
}
sequence
getAndIncrement()
和
set()
操作组合仍然安全吗?
用if statement确保一个带有local=10000
i我更新了上面的方法,希望它根据规格和线程安全
public class SequenceGenerator {
private static final SequenceGenerator GENERATOR = new
SequenceGenerator();
private final AtomicInteger sequence = new
AtomicInteger(0);
private final AtomicInteger resetCount = new
AtomicInteger(0);
private final Object resetLock = new Object();
private SequenceGenerator() {}
public static SequenceGenerator getInstance() {
return GENERATOR;
}
/**
* This method a unique sequenceId that follow this format
* [ResetCount-SequenceNumber]. The SequenceNumber range is [0000,9999]
* and every time the max value 9999 exceeds, it will reset back to zero
* and the ResetCount value will increase by one.
*
* @return a unique sequenceId in literal format
*/
public String generateSequenceId() {
while (true) {
int local = sequence.getAndIncrement();
if (local <= 9999) {
//Do some work and return a unique sequence number literal
return resetCount+"-"+local;
} else {
//Reset after the sequence exceeds 4 digits
//Only a thread with variable local=10000 should
//reset sequence back to zero(0)
synchronized(resetLock){
if(sequence.get()>=10000){
sequence.set(0);
resetCount.incrementAndGet();
}
}
}
}
}
}
该代码绝对不安全。正如某人在评论中指出的那样,无法保证线程执行
sequence.set(0);
resetCount.incrementAndGet();
通话后和打电话之前不暂停之间的暂停。可能有许多其他线程在这两个语句之间调用您的方法,并且这些线程中的每个人都会生成重复(因为他们看到低于10_000的值,并使用
old
值resetCount.incrementAndGet();
)