【发布时间】:2019-02-19 14:46:26
【问题描述】:
在过去的几天里,我读了一些关于无锁编程的文章,我遇到了 util.java.Random 类,它使用以下例程创建它的位:
protected int next(int bits) {
long oldseed, nextseed;
AtomicLong seed = this.seed;
do {
oldseed = seed.get();
nextseed = (oldseed * multiplier + addend) & mask;
} while (!seed.compareAndSet(oldseed, nextseed));
return (int)(nextseed >>> (48 - bits));
}
根据this answer to a post "Spinlock vs Busy wait":
所谓的无锁算法倾向于使用紧忙等待 CAS指令,但在一般情况下争用如此之低 CPU 通常只需要迭代几次。
还有Wikipedia topic "Compare-and-Swap":
而不是在 CAS 操作失败后立即重试, 研究人员发现,整体系统性能可以提高 在多处理器系统中——许多线程不断更新一些 特定的共享变量——如果看到 CAS 的线程使用失败 指数退避——换句话说,在重试之前稍等片刻 CAS.[4]
Wikipedia 上的文章能看懂吗,已经查出来了,但是还没有使用,或者 CAS 指令失败后人为回退是常见的做法。这是因为这种循环在 CPU 使用率方面不被认为是危险的,还是因为 CAS 没有经常争用?
第二个问题:是否有任何特定原因创建了对 seed 的引用,或者我们也可以简单地使用类范围中的变量?
【问题讨论】:
-
这是很少有争议的,它极不可能循环,甚至更不可能循环多次。
-
@PeterLawrey 特别是因为在多线程应用程序中使用
Random的建议是不使用Random,而是使用ThreadLocalRandom,如文档所述: “java.util.Random的实例是线程安全的。但是,跨线程同时使用同一java.util.Random实例可能会遇到争用,从而导致性能下降。请考虑在多线程设计中使用ThreadLocalRandom”。 ;-)
标签: java concurrency lock-free compare-and-swap