gpt4 book ai didi

java - 与StampedLock 的竞争条件?

转载 作者:行者123 更新时间:2023-12-02 10:51:01 25 4
gpt4 key购买 nike

我正在尝试为 Hibernate 实现我自己的序列生成器。开箱即用的方法带有同步方法,这会导致我的应用程序出现过多争用(多个线程并行地将数据插入 Oracle 数据库)。

我想尝试一下 StampedLock,但不幸的是,我的测试用例(150.000 行,16 个线程)总是在 150.000 次执行中产生 5-15 次 id 冲突。

附上我的代码,您知道我做错了什么吗?或者您可以建议更好的方法吗?谢谢。

import java.io.Serializable;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.StampedLock;

import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.id.IntegralDataTypeHolder;
import org.hibernate.id.SequenceGenerator;

public class HighConcurrencySequenceGenerator extends SequenceGenerator
{
private StampedLock lock = new StampedLock();

private AtomicLong sequenceValue; // the current generator value
private IntegralDataTypeHolder lastSourceValue; // last value read from db
private IntegralDataTypeHolder upperLimitValue; // the value to query the db again

@Override
public Serializable generate( SessionImplementor session, Object object )
{
long stamp = this.lock.readLock();
try
{
while ( needsSequenceUpdate() )
{
long ws = this.lock.tryConvertToWriteLock( stamp );
if ( ws != 0L )
{
stamp = ws;
return fetchAndGetNextSequenceValue( session );
}
this.lock.unlockRead( stamp );
stamp = this.lock.writeLock();
}
return getNextSequenceValue();
}
finally
{
this.lock.unlock( stamp );
}
}

private long fetchAndGetNextSequenceValue( SessionImplementor session )
{
this.lastSourceValue = generateHolder( session );
long lastSourceValue = this.lastSourceValue.makeValue()
.longValue();
this.sequenceValue = new AtomicLong( lastSourceValue );

long nextVal = getNextSequenceValue();

this.upperLimitValue = this.lastSourceValue.copy()
.add( this.incrementSize );
return nextVal;
}

private long getNextSequenceValue()
{
long nextVal = this.sequenceValue.getAndIncrement();
return nextVal;
}

private boolean needsSequenceUpdate()
{
return ( this.sequenceValue == null ) || !this.upperLimitValue.gt( this.sequenceValue.get() );
}
}

最佳答案

这段代码不是线程安全的

this.sequenceValue = new AtomicLong( lastSourceValue );

在最坏的情况下,您最终会得到 N 个具有相同内容的 AtomicLong 实例值,其中 N 是正在运行的线程数。

关于java - 与StampedLock 的竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52187128/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com