Java double checked locking - Strings

后端 未结 2 602
猫巷女王i
猫巷女王i 2021-01-28 10:52

Given that strings contain final field, does it mean in the context of double checked locking it is not necessary to declare them volatile? E.g.

<
2条回答
  •  余生分开走
    2021-01-28 11:32

    No, you still have to declare val as volatile here. The problem is that while String is immutable and thread safe, val is not. You still have a visibility problem with val itself.

    To address your point about "given that String contains a final field," note that the JLS specifically says that visibility is not transitive when dealing with final fields.

    Given a write w, a freeze f, an action a (that is not a read of a final field), a read r1 of the final field frozen by f, and a read r2 such that hb(w, f), hb(f, a), mc(a, r1), and dereferences(r1, r2), then when determining which values can be seen by r2, we consider hb(w, r2). (This happens-before ordering does not transitively close with other happens-before orderings.)

    https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.5

    Where a "freeze f" is how the JLS refers to the thread-safe part of final field semantics, i.e., the part that actually makes the object referenced by the field visible.

    (There are cases where you can rely on transitivity with synchronizes-with and happens-before. Brian Goetz calls this 'piggy-backing' and talks about it in Java Concurrency in Practice. But it's pretty much experts only and I don't recommend it until you are an expert with the Java memory model.)

    In short, declare val volatile and don't worry about saving two nanoseconds by skipping synchronization. The extra rigmarole in the code isn't worth it, and it doesn't work anyway.

提交回复
热议问题