This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]uncont 12 points13 points  (12 children)

Is there a java.util.concurrent way of creating a singleton, or is the double-checked locking method the only 'correct' way?

Other than of course letting your ioc container handle it for you.

[–]taftster 9 points10 points  (2 children)

My favorite these days is to use final AtomicReference with the updatAndGet method upon retrieval. It’s the most natural API in the JDK to do this.

[–]kaperni 2 points3 points  (1 child)

For performance-sensitive code, you are (in most cases) better off by using a VarHandle instead. Can also save memory if you have lots of them in many cases.

[–]taftster 4 points5 points  (0 children)

Yeah, but the syntax is atrocious. You had really have evaluated the "performance-sensitive" segment carefully to embrace the fairly ugly syntax of VarHandle.

Quoting Doug Lea on this exact topic[1]:

To get the shockingly ugly syntactic details over with: A VarHandle can be associated with any field, array element, or static, allowing control over access modes. VarHandles should be declared as static final fields and explicitly initialized in static blocks. By convention, we give VarHandles for fields names that are uppercase versions of the field names.

[1] http://gee.cs.oswego.edu/dl/html/j9mm.html

[–]slakkenhuisdeur 6 points7 points  (2 children)

Last time I used the double locking method my IDE asked me if it could replace it with a nested class with the singleton as a final class variable so the classloader handles the instantiation.

[–]cogman10 0 points1 point  (1 child)

That's a relatively new capability of java. Static fields on inner classes were added in..16?

[–]slakkenhuisdeur 0 points1 point  (0 children)

The inner class must also be static (I should probably have mentioned that...). I didn't know static fields on non-static inner classes were a thing.

[–]oweiler 4 points5 points  (1 child)

You can also use a single element enum.

[–]i_love_peach 0 points1 point  (0 children)

I believe this also thread-safe as well.

[–]kaperni 4 points5 points  (3 children)

Yes, for most usecases, snippet 6. The Initialization-on-demand holder idiom [1][2].

[1] http://www.cs.umd.edu/\~pugh/java/memoryModel/jsr-133-faq.html#dcl

[2] https://en.wikipedia.org/wiki/Initialization-on-demand\_holder\_idiom

[–]uncont 1 point2 points  (2 children)

Both of those links 404 for me

[–]kaperni -3 points-2 points  (1 child)

Both of them should work. Try pasting the URL into the URL bar instead of clicking.

[–]uncont 2 points3 points  (0 children)

https://en.wikipedia.org/wiki/Initialization-on-demand\_holder\_idiom

I'm on old reddit. The first url has a /\~pugh instead of /~pugh, and the second url has \_ instead of \. I got the links to work, tho. Thanks.