Discussion:
initialization of two latches
Ted Yu
2014-01-26 16:50:10 UTC
Permalink
Hi,
Suppose one class has two latches:
    private volatile CountDownLatch safePointAttainedLatch = new CountDownLatch(1);
    privatevolatileCountDownLatch safePointReleasedLatch= newCountDownLatch(1);


And this method:
    /**
     * @return True is this is a 'cocked', fresh instance, and not one that has already fired.
     */
    boolean isCocked() {
      return this.safePointAttainedLatch.getCount() > 0 &&
        this.safePointReleasedLatch.getCount() > 0;
    }
There is a chance that safePointAttainedLatch is initialized while the other is not.
What's a better way to implement isCocked() ?

Thanks
Jim White
2014-01-26 17:44:36 UTC
Permalink
You need to use a single volatile pointer to ensure atomicity of assignment. Create a Trigger class with the two latches and the isCocked method. The pointer to the trigger can be volatile but those for the latches should not be.

Jim

Sent from my iPad

------------------------------------

Yahoo Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/seajug/

<*> Your email settings:
Individual Email | Traditional

<*> To change settings online go to:
http://groups.yahoo.com/group/seajug/join
(Yahoo! ID required)

<*> To change settings via email:
seajug-digest-***@public.gmane.org
seajug-fullfeatured-***@public.gmane.org

<*> To unsubscribe from this group, send an email to:
seajug-unsubscribe-***@public.gmane.org

<*> Your use of Yahoo Groups is subject to:
http://info.yahoo.com/legal/us/yahoo/utos/terms/
George Smith
2014-01-26 17:52:11 UTC
Permalink
Ted,

1st, the "volatile" are of no value, as the latch objects are doing the
magic, not the latch references, and "volatile" is only being applied to
the reference. As such I would make them final.
2nd, "final" fields initialized in the field reference execute BEFORE the
called constructor, so even if one lets "this" leak out of a constructor (a
bad practice), then the fields WILL be initialized.

George
Hi,
private volatile CountDownLatch safePointAttainedLatch = newCountDownLatch(1);
private volatile CountDownLatch safePointReleasedLatch = newCountDownLatch(1);
/**
that has already fired.
*/
boolean isCocked() {
return this.safePointAttainedLatch.getCount() > 0 &&
this.safePointReleasedLatch.getCount() > 0;
}
There is a chance that safePointAttainedLatch is initialized while the
other is not.
What's a better way to implement isCocked() ?
Thanks
--
"And the users exclaimed with a laugh and a taunt: It's just what we
asked for but not what we want." -- Unknown
Ted
2014-01-26 18:35:26 UTC
Permalink
Thanks for the reply, George.
Ted,
1st, the "volatile" are of no value, as the latch objects are doing the magic, not the latch references, and "volatile" is only being applied to the reference. As such I would make them final.
2nd, "final" fields initialized in the field reference execute BEFORE the called constructor, so even if one lets "this" leak out of a constructor (a bad practice), then the fields WILL be initialized.
George
Post by Ted Yu
Hi,
private volatile CountDownLatch safePointAttainedLatch = new CountDownLatch(1);
private volatile CountDownLatch safePointReleasedLatch = new CountDownLatch(1);
/**
*/
boolean isCocked() {
return this.safePointAttainedLatch.getCount() > 0 &&
this.safePointReleasedLatch.getCount() > 0;
}
There is a chance that safePointAttainedLatch is initialized while the other is not.
What's a better way to implement isCocked() ?
Thanks
--
"And the users exclaimed with a laugh and a taunt: It's just what we asked for but not what we want." -- Unknown
j***@public.gmane.org
2014-01-26 19:02:03 UTC
Permalink
It is true that we don't see any effect from volatile in this local context. It's semantics are non-local and can be important for the type of application that is hinted at here.


A volatile member is assured of causing ordered access to shared memory which is relevant in many concurrent systems (which we know is at least the case here since we're told that it possible that isCocked could be interleaved with the assignments to the latches).


They are also not serialized and so you would want to use this to ensure that the represented state is coherent with the environment.


But my answer was not trying to get into all the myriad potential complexities of this sort of systems, but just talking about how to ensure a coherent atomic update with the Java memory model, and that it is to use a single volatile pointer.


Jim
j***@public.gmane.org
2014-01-26 19:37:58 UTC
Permalink
Whoops, I conflated volatile and transient there. Been doing Groovy stuff so long my concurrent Java jazz is a bit rusty (but I've doing some Android stuff lately and so having to do a bit of plain old Java again).


And as for the use of final to address this issue, the thing that would need to be final is the class (i.e. Trigger) that contains the members. As long as there is no subclassing then the initializers of the members will be called before any of the other instance methods (as long as the initializers don't call those methods themselves).


Jim

Continue reading on narkive:
Search results for 'initialization of two latches' (Questions and Answers)
10
replies
building a computer...?
started 2008-07-10 16:12:09 UTC
desktops
Loading...