Brian Goetz的不当出版物 [英] Brian Goetz's improper publication

查看:141
本文介绍了Brian Goetz的不当出版物的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题已在 before 之前发布,但没有提供真正的示例作品。所以Brian提到在某些条件下,AssertionError可以发生在下面的代码中:

The question has been posted before but no real example was provided that works. So Brian mentions that under certain conditions the AssertionError can occur in the following code:

public class Holder {
  private int n;
  public Holder(int n) { this.n = n; }

  public void assertSanity() {
    if (n!=n)
      throw new AssertionError("This statement is false");
  }
}

持有人不当发布时如下:

When holder is improperly published like this:

class someClass {
    public Holder holder;

    public void initialize() {
        holder = new Holder(42);
    }
}



我理解这将发生在在对象持有者的实例变量对另一个线程可见之前变为可见。所以我做了下面的例子来激发这种行为,因此AssertionError与下面的类:

I understand that this would occur when the reference to holder is made visible before the instance variable of the object holder is made visible to another thread. So I made the following example to provoke this behavior and thus the AssertionError with the following class:

public class Publish {

  public Holder holder;

  public void initialize() {
    holder = new Holder(42);
  }

  public static void main(String[] args) {
    Publish publish = new Publish();
    Thread t1 = new Thread(new Runnable() {
      public void run() {
        for(int i = 0; i < Integer.MAX_VALUE; i++) {
          publish.initialize();
        }
        System.out.println("initialize thread finished");
      }
    });

    Thread t2 = new Thread(new Runnable() {
      public void run() {
        int nullPointerHits = 0;
        int assertionErrors = 0;
        while(t1.isAlive()) {
          try {
            publish.holder.assertSanity();
          } catch(NullPointerException exc) {
            nullPointerHits++;
          } catch(AssertionError err) {
            assertionErrors ++;
          }
        }
        System.out.println("Nullpointerhits: " + nullPointerHits);
        System.out.println("Assertion errors: " + assertionErrors);
      }
    });

    t1.start();
    t2.start();
  }

}

无论我跑多少次代码,AssertionError永远不会发生。所以对我来说有几个选择:

No matter how many times I run the code, the AssertionError never occurs. So for me there are several options:


  • jvm实现(在我的例子中是Oracle的1.8.0.20)强制在构建过程中设置不变量

  • 这本书是错误的,我会怀疑,作者是Brian Goetz ... nuf说

  • 我在上面的代码中做错了

所以我的问题:
- 的AssertionError成功?用什么代码呢?
- 为什么我的代码不会引发AssertionError?

So the questions I have: - Did someone ever provoke this kind of AssertionError successfully? With what code then? - Why isn't my code provoking the AssertionError?

推荐答案

您的程序未正确同步,该术语由Java内存模型定义。

Your program is not properly synchronized, as that term is defined by the Java Memory Model.

但是,这并不意味着任何特定的运行会显示你正在寻找的断言失败,也不一定能够期望看到失败。这可能是,你的特定的VM只是恰好处理这个特定的程序,以某种方式,决不会暴露同步失败。或者它可能会出现虽然容易失败,可能性是远程的。

That does not, however, mean that any particular run will exhibit the assertion failure you are looking for, nor that you necessarily can expect ever to see that failure. It may be that your particular VM just happens to handle that particular program in a way that turns out never to expose that synchronization failure. Or it may turn out the although susceptible to failure, the likelihood is remote.

不,你的测试没有提供任何理由,编写代码无法正确同步以这种特定的方式。您无法推导出这些观察结果。

And no, your test does not provide any justification for writing code that fails to be properly synchronized in this particular way. You cannot generalize from these observations.

这篇关于Brian Goetz的不当出版物的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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