2

Let's say I have a static int that affects behaviour of the class.

class A{
    public static int classFlag = 0;
    private int myFlag = 0;

    public void doSomething(){
        if(myFlag != classFlag){
             myFlag = classFlag:
        }

        /*myFlag-dependent behaviour*/
    }
}

There's exactly one thread in the system that changes classFlag, and /*myFlag-dependent behaviour*/ does not require that an update to classFlag is immediately visible to all threads.

I would therefore like to keep the classFlag non-volatile to avoid introducting a costly and completely unnecessary memory barrier.

Can I rely on an update to classFlag being eventually visible?

User1291
  • 7,664
  • 8
  • 51
  • 108
  • 1
    relying on the guarantee of a `public`, `static`, mutable field being modified by only one thread? Sounds like a recipe for disaster – Rogue Nov 17 '17 at 09:43
  • 1
    (1) No you can't (2) volatile reads are not very expensive. – assylias Nov 17 '17 at 09:43
  • https://stackoverflow.com/questions/4633866/is-volatile-expensive – assylias Nov 17 '17 at 09:44
  • @Rogue well, the system will guarantee as much. outside of hardware failures or gross blunders in implementation, ``classFlag`` is exposed to exactly one thread only (which I can guarantee because that field gets inserted at compile-time) – User1291 Nov 17 '17 at 09:50
  • @assylias I'm not concerned about the cost of reading the volatile per se. I'm concerned about the cost of the ``happens-before`` guarantees a write to it triggers. (assume I have a system with a few hundred threads running). – User1291 Nov 17 '17 at 09:53
  • @User1291 The number of threads is somewhat irrelevant - once a cpu has updated the value of the field, all the threads running on that cpu will see the new value. But the bottom line is that a thread may *never* see the updated value (whether it will happen depends on the cpu architecture etc.). What do you mean by "inserted at compile time"? – assylias Nov 17 '17 at 10:07
  • @assylias class ``A`` doesn't *actually* have any of the flag-dependent bits of the behaviour. I'm instrumenting the bytecode to add them, along with the flag fields. Would you like to make an answer out of your comment and elaborate on your "no, you can't"? – User1291 Nov 17 '17 at 10:16
  • It doesn't take a gross blunder in implementation, in fact it takes a very, very small one. Any calls to methods which affect that flag also can only be done with the same thread, etc. Classes checking the variable outside the class are affected similarly. – Rogue Nov 17 '17 at 10:47
  • @Rogue all methods modifiying ``classFlag`` are private to the one thread that does the updates. All classes that have a ``classFlag`` *only* ever read it. other than the one modifying thread, there are no classes that access a different ``classFlag`` than their own. that much, we can guarantee by design. And to "accidentally" change it from user code, you'd need to use either ``Unsafe`` or ``Reflection`` -- which the system explicitly prohibits. I don't quite see how we are still in danger. – User1291 Nov 17 '17 at 11:01
  • So you have multiple of these `public static` fields? And only the class itself refers to it? So why not a `private static` field? – Rogue Nov 17 '17 at 18:55
  • @Rogue because the one dedicated modifying thread also needs access to it. Java doesn't allow for more fine-grained access control. – User1291 Nov 17 '17 at 19:28

1 Answers1

0

The reader thread that executes a piece of code based on myFlag will not be able to see your update, which can result in 1) very uncertain behavior 2) a missed update (you never know when will this ::doSomething be called again)

I think cost of volatile is low enough to warrant it's correct usage rather than leaving code with such bugs.

Dev Amitabh
  • 185
  • 1
  • 4