0

我有以下代码。显然,Reference 类不是线程安全的,因为它不保护它的“reference”属性。我如何证明我需要通过例如 Atomicreference 来保护它?

当我运行以下 JUnit 测试时,它在两个 Windows 上都成功:Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz 和 Linux:Intel(R) Xeon(R) CPU X5670 @ 2.93GHz,使用 JRE 1.7.0_15。

import java.util.concurrent.CountDownLatch;
import org.junit.Test;
import static org.junit.Assert.assertTrue;

public class AssignReferenceTest {
    private static class Reference {
        private Object reference = null;

        private void setReference(Object reference) {
            this.reference = reference;
        }

        boolean hasReference() {
            return reference != null;
        }
    }

    @Test
    public void runManyTimes() throws Exception {
        for (int i = 0; i < 100000; i++) {
            testReferenceVisibilityProblem();
        }
    }

    public void testReferenceVisibilityProblem() throws Exception {
        final Reference reference = new Reference();
        final CountDownLatch latch = new CountDownLatch(1);

        Thread writeThread = new Thread(new Runnable() {
            public void run() {
                reference.setReference(new Object());
                latch.countDown();
            }
        });
        Thread readThread = new Thread(new Runnable() {
            public void run() {
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                assertTrue("Should have the reference", reference.hasReference());
            }
        });

        writeThread.start();
        readThread.start();
        writeThread.join();
        readThread.join();
    }
}
4

1 回答 1

4

您的代码是线程安全的,因为 CountDownLatch 保证在await()返回之前完成的每个更改都发生在之后的所有操作之前。

请参阅http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html

“释放”同步器方法(例如 Lock.unlock、Semaphore.release 和 CountDownLatch.countDown)之前的操作发生在成功“获取”方法(例如 Lock.lock、Semaphore.acquire、Condition.await 和 CountDownLatch)之后的操作.await 在另一个线程中的同一个同步器对象上。

于 2013-08-21T14:15:46.900 回答