可以通过线程安全的方式安全地递增BigInteger,也许使用AtomicReference而不加锁吗? [英] Possible to safely increment BigInteger in a thread safe way, perhaps with AtomicReference, w/o locking?

查看:209
本文介绍了可以通过线程安全的方式安全地递增BigInteger,也许使用AtomicReference而不加锁吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的很多代码都是旧代码,但是我们正在迁移到大数据"后端,我正在努力推广更新的API调用,鼓励使用最新的Spring库等.我们的问题之一是应用层ID生成.由于我不明白的原因,上级机构希望使用顺序的BigInteger.我本可以通过重新生成使它们随机化,然后对失败的插入进行重试,但我确实被否决了.

A lot of our code is legacy but we are moving to a "Big Data" back-end and I'm trying to evangelize the newer API calls, encourage the use of the latest Spring libraries etc. One of our problems is application layer ID generation. For reasons I don't understand, a higher authority wants sequential BigInteger's. I would have made them random with re-generate and re-try on failed insertions but I done got vetoed.

撇开抱怨,我处于一个需要递增并跨线程获取BigInteger的位置,并且以一种安全,高效的方式进行操作.我以前从未使用过AtomicReference,但对于此应用程序来说,它看起来非常接近完美.现在,我们有一个同步的代码块,这严重损害了我们的性能.

Grumbling aside, I'm in a position where I need to increment and get a BigInteger across threads and do it in a safe and performant manner. I've never used AtomicReference before but it looks pretty close to perfect for this application. Right now we have a synchronized code block which hurts our performance pretty badly.

这是正确的方法吗?语法示例?

Is this the right way to go? Syntax examples?

我应该提到此模块的工作方式,它使用存储过程访问数据库以获取要使用的一系列值.一次成千上万,因此它可能仅在20分钟内发生一次.这样可以防止各种服务器相互踩踏,但是也增加了必须将BigInteger设置为任意后续值的麻烦.当然,这也必须是线程安全的.

I should mention that the way this module works, it hits the database using a Stored Procedure to grab a range of values to use. Tens of thousands at a time so that it only happens maybe once in 20 minutes. This keeps the various servers from stepping on each-other but it also adds the wrinkle of having to set the BigInteger to an arbitrarily subsequent value. Of course, that needs to be thread safe also.

P.S.我仍然认为随机生成的想法比处理所有这些线程的东西要好. BigInteger是一个非常大的数字,曾经两次生成相同整数的几率必须接近零.

P.S. I still think my random generation idea is better than handling all this threading stuff. A BigInteger is a ridiculously large number and the odds of ever generating the same one twice have to be close to nil.

推荐答案

可以使用AtomicReference进行快速草稿:

It is possible using AtomicReference here's a quick draft :

public final class AtomicBigInteger {

    private final AtomicReference<BigInteger> valueHolder = new AtomicReference<>();

    public AtomicBigInteger(BigInteger bigInteger) {
        valueHolder.set(bigInteger);
    }

    public BigInteger incrementAndGet() {
        for (; ; ) {
            BigInteger current = valueHolder.get();
            BigInteger next = current.add(BigInteger.ONE);
            if (valueHolder.compareAndSet(current, next)) {
                return next;
            }
        }
    }
}

它基本上是incrementAndGet()

这篇关于可以通过线程安全的方式安全地递增BigInteger,也许使用AtomicReference而不加锁吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆