Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在实践中理解java并发性这本书的一个例子?_Java_Concurrency_Assertions_Java Threads - Fatal编程技术网

如何在实践中理解java并发性这本书的一个例子?

如何在实践中理解java并发性这本书的一个例子?,java,concurrency,assertions,java-threads,Java,Concurrency,Assertions,Java Threads,清单3.15。如果未正确发布,则有失败风险的类别 我的第一个问题是,如果(n!=n),为什么javac不优化 下面是我的示例演示 public class TestSync { private int n; public TestSync(int n) { this.n = n; } public void assertSanity() { if(n!=n) throw new AssertionErro

清单3.15。如果未正确发布,则有失败风险的类别

我的第一个问题是,如果(n!=n),为什么javac不优化

下面是我的示例演示

public class TestSync {
    private int n;

    public TestSync(int n) {
        this.n = n;
    }

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

    private static TestSync test;
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(true) {
                    if(test == null) test = new TestSync(2);
                    else test = null;
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while(true) {
                    if(test != null)
                        try {
                            test.assertSanity();
                        } catch (NullPointerException e) {

                        }
                }
            }
        }).start();
    }
}
我的第二个问题是我做的对吗?因为在我运行演示时没有发生异常

更新

1.除了我的第一个问题外:
javap-ctestsync.class

public void assertSanity();
    Code:
       0: aload_0
       1: getfield      #3                  // Field n:I
       4: aload_0
       5: getfield      #3                  // Field n:I
       8: if_icmpeq     21
      11: new           #4                  // class java/lang/AssertionError
      14: dup
      15: ldc           #5                  // String This statement is false
      17: invokespecial #6                  // Method java/lang/AssertionError."<init>":(Ljava/lang/Object;)V
      20: athrow
      21: return
public void assertSanity();
代码:
0:aload_0
1:getfield#3//字段n:I
4:aload_0
5:getfield#3//字段n:I
8:if_icmpeq 21
11:new#4//class java/lang/AssertionError
14:dup
15:ldc#5//String这句话是假的
17:invokespecial#6//方法java/lang/AssertionError.“:(Ljava/lang/Object;)V
20:athrow
21:返回
我认为javac会将
if(n!=n)
优化为
if(false)
,并将其缩小

2.为什么我仍然在
if(test!=null)
之后添加
try{}catch(NullPointerException e)


因为我认为字段
test
可能由
之后的另一个线程设置
null
,如果(test!=null)

首先,
javac
几乎从不优化代码,您正在编译。只有当值是编译时常量时,才需要
javac
在编译时对表达式求值,而表达式本身就是编译时常量,请参阅

然而,操作在运行时会得到优化,即使没有线程同步措施,优化器也可以使用乐观的假设,比如变量在两次读取之间不会改变。所以
n=n
表达式一开始计算为
true
的可能性很低,因为两次读取之间的时间很短,并且在优化器启动后几乎永远不会为
true
。所以当表达式
n=n
不能保证总是
,在实践中不太可能遇到

当然,根据墨菲定律,不管怎样,当你试图挑起错误时,它永远不会发生,但偶尔会发生在客户身上,但永远不会重现


⑨注意,即使第二个线程由于争用条件读取初始值
0
n=n
如果在随后的读取中不再次读取首字母
0
,则只会失败。

问题是什么?你怎么知道javac没有优化它?为什么在空对象的if语句中有一个NullPointerException的try-catch?@cricket\u 007已经更新了我的问题我可能是错的,但是
test
应该是
synchronized
?@cricket\u 007是的,但是我想让示例按照假设的那样抛出AssertionError异常到n=n表达式以一个很低的可能性开始,我认为
false
应该是
true
你是对的。
n=n
非常不自然,很容易混淆。
public void assertSanity();
    Code:
       0: aload_0
       1: getfield      #3                  // Field n:I
       4: aload_0
       5: getfield      #3                  // Field n:I
       8: if_icmpeq     21
      11: new           #4                  // class java/lang/AssertionError
      14: dup
      15: ldc           #5                  // String This statement is false
      17: invokespecial #6                  // Method java/lang/AssertionError."<init>":(Ljava/lang/Object;)V
      20: athrow
      21: return