Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Main page
Recent changes
Random page
Help about MediaWiki
Special pages
Niidae Wiki
Search
Search
Appearance
Create account
Log in
Personal tools
Create account
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
Double-checked locking
(section)
Page
Discussion
English
Read
Edit
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit
View history
General
What links here
Related changes
Page information
Appearance
move to sidebar
hide
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
== Usage in Java == As of [[Java Platform, Standard Edition|J2SE 5.0]], the [[Volatile variable|volatile]] keyword is defined to create a memory barrier. This allows a solution that ensures that multiple threads handle the singleton instance correctly. This new idiom is described in [http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html] and [http://www.oracle.com/technetwork/articles/javase/bloch-effective-08-qa-140880.html]. <syntaxhighlight lang="java"> // Works with acquire/release semantics for volatile in Java 1.5 and later // Broken under Java 1.4 and earlier semantics for volatile class Foo { private volatile Helper helper; public Helper getHelper() { Helper localRef = helper; if (localRef == null) { synchronized (this) { localRef = helper; if (localRef == null) { helper = localRef = new Helper(); } } } return localRef; } // other functions and members... } </syntaxhighlight> Note the local variable "{{mono|localRef}}", which seems unnecessary. The effect of this is that in cases where {{mono|helper}} is already initialized (i.e., most of the time), the volatile field is only accessed once (due to "{{mono|return localRef;}}" instead of "{{mono|return helper;}}"), which can improve the method's overall performance by as much as 40 percent.<ref>{{cite book |last1=Bloch |first1=Joshua |title=Effective Java |date=2018 |publisher=Addison-Wesley |isbn=978-0-13-468599-1 |page=335 |edition=Third |quote=On my machine, the method above is about 1.4 times as fast as the obvious version without a local variable.}}</ref> Java 9 introduced the {{Javadoc:SE|java/lang/invoke|VarHandle}} class, which allows use of relaxed atomics to access fields, giving somewhat faster reads on machines with weak memory models, at the cost of more difficult mechanics and loss of sequential consistency (field accesses no longer participate in the synchronization order, the global order of accesses to volatile fields).<ref>{{Cite web|url=https://docs.oracle.com/javase/specs/jls/se10/html/jls-17.html#jls-17.4.4|title=Chapter 17. Threads and Locks|website=docs.oracle.com|access-date=2018-07-28}}</ref> <syntaxhighlight lang="java"> // Works with acquire/release semantics for VarHandles introduced in Java 9 class Foo { private volatile Helper helper; public Helper getHelper() { Helper localRef = getHelperAcquire(); if (localRef == null) { synchronized (this) { localRef = getHelperAcquire(); if (localRef == null) { localRef = new Helper(); setHelperRelease(localRef); } } } return localRef; } private static final VarHandle HELPER; private Helper getHelperAcquire() { return (Helper) HELPER.getAcquire(this); } private void setHelperRelease(Helper value) { HELPER.setRelease(this, value); } static { try { MethodHandles.Lookup lookup = MethodHandles.lookup(); HELPER = lookup.findVarHandle(Foo.class, "helper", Helper.class); } catch (ReflectiveOperationException e) { throw new ExceptionInInitializerError(e); } } // other functions and members... } </syntaxhighlight> If the helper object is static (one per class loader), an alternative is the [[initialization-on-demand holder idiom]]<ref>Brian Goetz et al. Java Concurrency in Practice, 2006 pp348</ref> (See Listing 16.6<ref name=JCP>{{cite web|last1=Goetz|first1=Brian|title=Java Concurrency in Practice β listings on website|url=http://jcip.net.s3-website-us-east-1.amazonaws.com/listings.html|access-date=21 October 2014|display-authors=etal}}</ref> from the previously cited text.) <syntaxhighlight lang="java"> // Correct lazy initialization in Java class Foo { private static class HelperHolder { public static final Helper helper = new Helper(); } public static Helper getHelper() { return HelperHolder.helper; } } </syntaxhighlight> This relies on the fact that nested classes are not loaded until they are referenced. Semantics of {{mono|final}} field in Java 5 can be employed to safely publish the helper object without using {{mono|volatile}}:<ref>[https://mailman.cs.umd.edu/mailman/private/javamemorymodel-discussion/2010-July/000422.html] Javamemorymodel-discussion mailing list{{Stale|text=Page not found β consider updating the link}}</ref> <syntaxhighlight lang="java"> public class FinalWrapper<T> { public final T value; public FinalWrapper(T value) { this.value = value; } } public class Foo { private FinalWrapper<Helper> helperWrapper; public Helper getHelper() { FinalWrapper<Helper> tempWrapper = helperWrapper; if (tempWrapper == null) { synchronized (this) { if (helperWrapper == null) { helperWrapper = new FinalWrapper<Helper>(new Helper()); } tempWrapper = helperWrapper; } } return tempWrapper.value; } } </syntaxhighlight> The local variable {{mono|tempWrapper}} is required for correctness: simply using {{mono|helperWrapper}} for both null checks and the return statement could fail due to read reordering allowed under the Java Memory Model.<ref>[http://jeremymanson.blogspot.ru/2008/12/benign-data-races-in-java.html] {{cite web |last1=Manson |first1=Jeremy |date=2008-12-14 |title=Date-Race-Ful Lazy Initialization for Performance β Java Concurrency (&c) |url=http://jeremymanson.blogspot.ru/2008/12/benign-data-races-in-java.html |access-date=3 December 2016}}</ref> Performance of this implementation is not necessarily better than the {{mono|volatile}} implementation.
Summary:
Please note that all contributions to Niidae Wiki may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Encyclopedia:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Search
Search
Editing
Double-checked locking
(section)
Add topic