BigInteger Thread安全吗?

时间:2015-09-15 03:40:39

标签: java biginteger

我需要通过多个线程更新全局BigInteger值 - BigInteger线程安全吗?

5 个答案:

答案 0 :(得分:10)

BigInteger 对象是immutable objects的代表性示例 简单地说:

  

每个不可变的对象都是线程安全的,但引用它   is not

对于不可变对象,状态在整个生命周期内都是固定的。因为没有改变它的选择因此每个"改变"操作相当于用新对象替换。因此,在特定参考上的N个线程并行执行一系列修改之后,结果值很难预测(某些更新可能会丢失 - 未被注意)。
同样的故事是Integer课程。为克服这一限制,{strong> AtomicInteger
课程被引入JDK5 不幸的是,没有" AtomicBigInteger " JDK中的类。替代解决方案是使用 AtomicReference 包装对象实例 - 它作为代理使所有操作同步并且是原子的。

我提出了以下紧凑型解决方案,需要JDK 8:

final AtomicReference<BigInteger> valueHolder = new AtomicReference(BigInteger.ZERO);

使用此方法, BigInteger 提供的任何方法都可以重新表示为 lambda表达式,例如:

valueHolder.updateAndGet(x -> x.add(BigInteger.valueOf(10)));

要检查解决方案是否正确,您可以使用此代码段,使用并行流汇总所有低于100的整数(它是多线程操作):

IntStream.range(0, 100).parallel()
        .forEach(i -> valueHolder.updateAndGet(x -> x.add(BigInteger.valueOf(i))));

答案 1 :(得分:2)

您无法更新BigInteger,读取javadoc,它的不可变的任意精度整数。。要更新BigInteger字段,您需要将其替换为新的BigInteger,如此

...
bigInteger = bigInteger.add(value);
...

这将需要同步,否则可能会发生两件事:

  1. 一个线程更改了值,但其他线程没有看到更改

  2. 两个或多个线程同时添加但有些添加丢失。

答案 2 :(得分:1)

java.math.BigInteger是不可变的,因此多线程访问是安全的。

旁注:Thread-safety是一个术语,用于处理访问代码的多个线程(不仅仅是变量)。

答案 3 :(得分:0)

BigInteger是线程安全的。 但是你想要更新它,你应该使用这样的代码:

GT

所以同步是必要的。

答案 4 :(得分:0)

  

BigInteger不可变任意精度整数。

     

Immutable Objects:如果一个对象的状态在构造后无法改变,则该对象被认为是不可变的。最大限度地依赖不可变对象被广泛接受为用于创建简单,可靠代码的合理策略

这意味着BigInteger是线程安全的。