测试最终字段的初始化安全性 [英] Testing initialization safety of final fields

查看:64
本文介绍了测试最终字段的初始化安全性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图简单地测试JLS保证的最终字段的初始化安全性。这是我写的一篇论文。但是,根据我当前的代码,我无法让它失败。有人能告诉我我做错了什么,或者这只是我必须反复运行然后看到一个不幸的时机失败?

I am trying to simply test out the initialization safety of final fields as guaranteed by the JLS. It is for a paper I'm writing. However, I am unable to get it to 'fail' based on my current code. Can someone tell me what I'm doing wrong, or if this is just something I have to run over and over again and then see a failure with some unlucky timing?

这是我的代码:

public class TestClass {

    final int x;
    int y;
    static TestClass f;

    public TestClass() {
        x = 3;
        y = 4;
    }

    static void writer() {
        TestClass.f = new TestClass();
    }

    static void reader() {
        if (TestClass.f != null) {
            int i = TestClass.f.x; // guaranteed to see 3
            int j = TestClass.f.y; // could see 0

            System.out.println("i = " + i);
            System.out.println("j = " + j);
        }
    }
}

我的线程正在调用它像这样:

and my threads are calling it like this:

public class TestClient {

    public static void main(String[] args) {

        for (int i = 0; i < 10000; i++) {
            Thread writer = new Thread(new Runnable() {
                @Override
                public void run() {
                    TestClass.writer();
                }
            });

            writer.start();
        }

        for (int i = 0; i < 10000; i++) {
            Thread reader = new Thread(new Runnable() {
                @Override
                public void run() {
                    TestClass.reader();
                }
            });

            reader.start();
        }
    }
}

我已经运行了这个场景很多, 多次。我目前的循环产生10,000个线程,但我已经完成了1000,100000甚至一百万个。仍然没有失败。对于这两个值,我总是看到3和4。如何让它失败?

I have run this scenario many, many times. My current loops are spawning 10,000 threads, but I've done with this 1000, 100000, and even a million. Still no failure. I always see 3 and 4 for both values. How can I get this to fail?

推荐答案

从Java 5.0开始,您可以保证所有线程都会看到最终状态设置为构造函数。

From Java 5.0, you are guarenteed that all threads will see the final state set by the constructor.

如果你想看到这个失败,你可以试试像1.3这样的旧JVM。

If you want to see this fail, you could try an older JVM like 1.3.

我不会打印出每个测试,我只打印出失败。你可能会在一百万中失败,但却错过了。但是如果你只打印失败,它们应该很容易被发现。

I wouldn't print out every test, I would only print out the failures. You could get one failure in a million but miss it. But if you only print failures, they should be easy to spot.

一种更简单的方法就是添加到编写器中。

A simpler way to see this fail is to add to the writer.

f.y = 5;

并测试

int y = TestClass.f.y; // could see 0, 4 or 5
if (y != 5)
    System.out.println("y = " + y);

这篇关于测试最终字段的初始化安全性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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