未命名文件看看、
2021-09-04 23:27:24 1 举报
了了酷酷酷酷酷酷酷酷酷酷酷酷酷酷酷酷酷
作者其他创作
大纲/内容
流水号生成开始之前定义了两个缓存:SEQ_PARAM:(SequenceBank对象)1.序列号步长_banksize2.最大序列号_maxid3.序列号名称_name4.序列号计数_seqid5.序列号信息_seqinfo6.序列号长度_seqlength7.序列号开始_startidSEQ_BANK_MAP:(SequenceParam对象)1.当前序列号_curSeqId2.内存中最大序列号_maxSeqId3.序列号名称_seqNameLOAD_FACTOR:(负载因子 默认0.75) AtomicReference<Future<long>> preApplyFuture = new AtomicReference<>span style=\
判断SEQ_BANK_MAP是否存在seqName对应的缓存,如果存在的话就下一步,不存在更新缓存。
synchronize(seqname.intern())单线程执行
if存在原来加载过,已经开始启动取流水号
线程1
synchronized SequenceParam loadAndUpdateSeqParam()加载然后更新seqName对应的数据库中的数据。首先根据seqName更新流水号记录表中的sp_seq_Id自动加步长(sp_seq_id = sp_seq_id+bank_size)1.更新成功后根据seqName查询SequenceParameter对象如果对象存在,先判断这个seqName的流水号是否超过了数据库中记录的最大值,如果超过了,那就要重置流水号x数据库中重置成功后(sp_seq_id=sp_startid+sp_banksize)然后内存中对象也要重置。2.如果不更新那就抛出异常
if不存在第一次加载
输入:seqName
首先判读SEQ_PARAM缓存中是否有对应SeqName的缓存
根据返回的SequenceParam更新缓存SEQ_PARAM
根据返回的SequenceParam更新SequenceBank的缓存SEQ_BANK_MAP
第一个判断,如果内存中的maxSeq-curSeqId小于步长*0.75的负载因子。就说明此次流水号取值已经超过了此次步长的75%。这时,新建一个线程去预取操作。注意:这个预取不是一个个把它取出来,只是更新一下数据库的信息。新建线程执行,此时该代码块应该是有两线程正在执行。asynPreApplyMaxCacheId()预取方法,这里用了Lock对象,锁住这个方法。
线程2
流水号生成思维流程图
方法内部,使用了preApplyFuture原子类,原子类包了一个异步执行Future类,preApplyFuture.set(preApplyExecutor.submit(new Callable<Long>{(getNextSequenceFromDbRetry(seqName.sb))})getNextSequenceFromDbRetry 这个方法调用了updateSeqParam() 预先更新了数据库中的计数自动加步长,然后再更新SEQ_PARAM和SEQ_BANK_MAP缓存/
0 条评论
回复 删除
下一页