Will this AssertionError never be thrown in this case?

前端 未结 1 903
名媛妹妹
名媛妹妹 2021-01-21 08:27

First off the code, from JCIP listing http://jcip.net/listings/StuffIntoPublic.java and http://jcip.net/listings/Holder.java

public class SafePublication {
    p         


        
相关标签:
1条回答
  • 2021-01-21 08:48

    Yes, this is safe, because Thread#start guarantees happens-before. To be more wordy: any read/write to any variable that happens before Thread#start (I tend to think above in program order if you want), will also happen before any action within that Thread (it's run method).

    Indeed, that could happen to break and throw that error, if there were no happens before (to allow re-orderings) and if program execution would allow those potential re-orderings. I am even inclined to say and a proper CPU used with weak memory model (assuming you are on Intel, which is a strong memory model) could increase that chance, but I am not sure.

    So, as far as I can tell, the actions would take place in the following order: first the the publishing the reference is re-ordered with variable n (there is no happens-before, so this is allowed). Thread1 creates an instance of Holder. Thread2 sees that published reference and calls that method. It reads the variable n to be zero (remember that re-ordering happened and n is not yet written, thus has a default value of zero), so it then does the != check, but Thread1 that created Holder, writes n to be 12 for example before Thread2 reads it again (in the !=n part). So this can fail.

    Making the value final would solve this as it introduces the right memory barriers, or happens-before rules.

    0 讨论(0)
提交回复
热议问题