是此类线程安全性并遵循规格? [关闭]

问题描述 投票:0回答:1

下面的类实现包含两个字段。达到

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(); } } } } }
  1. sequence
    getAndIncrement()
    set()
    操作组合仍然安全吗?
  2. aanswer =

用if statement确保一个带有local=10000

的线程 权限将序列重置为零?
  1. aanswer = yyes,但仅用于并发请求少于或 等于19999年
    updates
  2. 基于下面的讨论和答案,认为复合AtomicInteger操作(多个)不是线程安全。学分 @solomonslow

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的值,并使用
java concurrency java.util.concurrent
1个回答
5
投票

old

resetCount.incrementAndGet();

	
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.