Return value of assignment operator in concurrent code

只谈情不闲聊 提交于 2019-11-26 19:57:15

问题


Given the following class:

class Foo {
  public volatile int number;

  public int method1() {
    int ret = number = 1;
    return ret;
  }

  public int method2() {
    int ret = number = 2;
    return ret;
  }
}

and given multiple threads calling method1() and method2() concurrently on the same Foo instance, can a call to method1() ever return anything other than 1?


回答1:


The JLS 15.26 specifies:

There are 12 assignment operators; all are syntactically right-associative (they group right-to-left). Thus, a=b=c means a=(b=c), which assigns the value of c to b and then assigns the value of b to a.

Ted Hopp's answer shows that Sun's javac doesn't follow this behaviour, possibly as an optimisation.

Due to the threading here, the behaviour of method1 would be undefined. If Sun's compiler makes the behaviour constant then it doesn't break from the undefined behaviour.




回答2:


I think the answer depends on the compiler. The language specifies:

At run-time, the result of the assignment expression is the value of the variable after the assignment has occurred.

I suppose that theoretically the value could be changed before the second (leftmost) assignment occurs.

However, with Sun's javac compiler, method1 will will turn into:

0:   aload_0
1:   iconst_1
2:   dup_x1
3:   putfield        #2; //Field number:I
6:   istore_1
7:   iload_1
8:   ireturn

This duplicates the constant 1 on the stack and loads it into number and then into ret before returning ret. In this case, it won't matter if the value stored in number is modified before assignment to ret, because 1, not number is being assigned.




回答3:


Either the statement contains a volatile read, or it doesn't contain a volatile read. There cannot be any ambiguity here, since volatile read is very important to program semantics.

If javac can be trusted, we can conclude that the statement doesn't involve a volatile read of number. The value of an assignment expression x=y is really just the value of y (after conversions).

We can also deduce that

    System.out.println(number=1);

does not involve reading number

    String s;

    (s="hello").length();

does not involve reading s

    x_1=x_2=...x_n=v

does not involve reading x_n, x_n-1, ...; instead, the value of v is directly assigned to x_i (after necessary conversions through types of x_n, ... x_i



来源:https://stackoverflow.com/questions/12850676/return-value-of-assignment-operator-in-concurrent-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!