java 原子性加法_java – 如何测试AtomicBoolean的原子性?

我正在为AtomicInteger和AtomicBoolean编写单元测试.它们将用作参考测试,用于在

objective-c中测试这些类的仿真,以用于翻译项目.

我认为AtomicInteger测试很好,主要是通过在大量for循环中执行可预测数量的递增,递减,加法和减法操作,每个循环都在自己的线程中运行(每个操作类型有很多线程).实际操作使用CountDownLatch同时启动.

当所有线程完成后,我通过比较原子整数和预期的整数值来断言,基于线程数,每个线程的迭代次数和每次迭代的预期增加/减少.这个测试通过.

但是如何测试AtomicBoolean?基本操作是get和set,因此在许多线程中多次调用并期望最终结果为true或false似乎没有意义.我正在考虑的方向是使用两个应始终具有相反值的AtomicBooleans.像这样:

@Test

public void testAtomicity() throws Exception {

// ==== SETUP ====

final AtomicBoolean booleanA = new AtomicBoolean(true);

final AtomicBoolean booleanB = new AtomicBoolean(false);

final int threadCount = 50;

final int iterationsPerThread = 5000;

final CountDownLatch startSignalLatch = new CountDownLatch(1);

final CountDownLatch threadsFinishedLatch = new CountDownLatch(threadCount);

final AtomicBoolean assertFailed = new AtomicBoolean(false);

// ==== EXECUTE: start all threads ====

for (int i = 0; i < threadCount; i++) {

// ==== Create the thread =====

AtomicOperationsThread thread;

thread = new AtomicOperationsThread("Thread #" + i, booleanA, booleanB, startSignalLatch, threadsFinishedLatch, iterationsPerThread, assertFailed);

System.out.println("Creating Thread #" + i);

// ==== Start the thread (each thread will wait until the startSignalLatch is triggered) =====

thread.start();

}

startSignalLatch.countDown();

// ==== VERIFY: that the AtomicInteger has the expected value after all threads have finished ====

final boolean allThreadsFinished;

allThreadsFinished = threadsFinishedLatch.await(60, TimeUnit.SECONDS);

assertTrue("Not all threads have finished before reaching the timeout", allThreadsFinished);

assertFalse(assertFailed.get());

}

private static class AtomicOperationsThread extends Thread {

// ##### Instance variables #####

private final CountDownLatch startSignalLatch;

private final CountDownLatch threadsFinishedLatch;

private final int iterations;

private final AtomicBoolean booleanA, booleanB;

private final AtomicBoolean assertFailed;

// ##### Constructor #####

private AtomicOperationsThread(final String name, final AtomicBoolean booleanA, final AtomicBoolean booleanB, final CountDownLatch startSignalLatch, final CountDownLatch threadsFinishedLatch, final int iterations, final AtomicBoolean assertFailed) {

super(name);

this.booleanA = booleanA;

this.booleanB = booleanB;

this.startSignalLatch = startSignalLatch;

this.threadsFinishedLatch = threadsFinishedLatch;

this.iterations = iterations;

this.assertFailed = assertFailed;

}

// ##### Thread implementation #####

@Override

public void run() {

super.run();

// ==== Wait for the signal to start (so all threads are executed simultaneously) =====

try {

System.out.println(this.getName() + " has started. Awaiting startSignal.");

startSignalLatch.await(); /* Awaiting start signal */

} catch (InterruptedException e) {

throw new RuntimeException("The startSignalLatch got interrupted.", e);

}

// ==== Perform the atomic operations =====

for (int i = 0; i < iterations; i++) {

final boolean booleanAChanged;

booleanAChanged = booleanA.compareAndSet(!booleanB.get(), booleanB.getAndSet(booleanA.get())); /* Set A to the current value of B if A is currently the opposite of B, then set B to the current value of A */

if (!booleanAChanged){

assertFailed.set(true);

System.out.println("Assert failed in thread: " + this.getName());

}

}

// ==== Mark this thread as finished =====

threadsFinishedLatch.countDown();

}

}

这适用于一个线程,但失败了多个.我想这是因为booleanAChanged = booleanA.compareAndSet(!booleanB.get(),booleanB.getAndSet(booleanA.get()));不是一个原子操作.

有什么建议?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值