This question already has answers here:
Java double checked locking
(11 answers)
Closed 8 years ago.
There's a common belief and multiple sources (including wiki) that claim this idiom to be an anti-pattern.
What are the arguments against using it in production code given the correct implementation is used (for example, using volatile)
What are the appropriate alternatives for implementing lazy initialization in a multithreaded environment ? Locking the whole method may become a bottleneck and even while modern synchronization is relatively cheap, it's still much slower especially under contention. Static holder seems to be a language-specific and a bit ugly hack (at least for me). Atomics-based implementation seems not be so different from traditional DCL while allowing multiple calculations or requires more complicated code. For example, Scala is still using DCL for implementing the lazy values while proposed alternative seems to be much more complicated.
Don't use double checked locking. Ever. It does not work. Don't try to find a hack to make it work, because it may not on a later JRE.
As far as I know, there is no other save way for lazy initialization than locking the whole object / synchronizing.
synchronized (lock) {
// lookup
// lazy init
}
For singletons the static holder (as #trashgod mentioned) is nice, but will not remain single if you have multiple classloaders.
If you require a lazy singleton in a multi-classloader environment, use the ServiceLoader.
Related
What was the driving factor or design plan in making the methods of HashTable synchronized?
This link says that HashTable is synchronized because its methods are synchronized. But, I want to know the reason "why" the methods were synchronized?
Was it just to provide some synchronization feature? A developer could explicitly handle a race condition through synchronization techniques. Why provide HashTable with this feature?
Keep in mind: these classes were created "ages" ago - when you check the javadoc for Hashtable, you find it says "since Java 1.0"; whereas HashMap says "1.2"!
Back then, Java was trying to compete with languages like C and C++; by providing unique selling points such as "built-in concurrency".
But people quickly figured that one better synchronizes containers when using them in multi-threaded environments!
So my (more of an opinion-based) answer is: at the time when this class was first designed, people assumed that the requirement "can be used by multiple threads" was more important than "gives optimal performance".
Because Java was "advertised" like: "use it to write multi-threaded write once run everywhere code". That approach fails quickly when the default container classes given to people need additional outside wrapping to actually make them "multi-threaded" ready.
During the years, the people behind Java started to understand that "more granular" solutions are required. Therefore the core collection classes are not synchronized to avoid the corresponding performance hits. Meaning: the default with collections is to go "unprotected"; so you have to put in some thoughts when your requirements is that "multi-threaded" correctness.
Same for "lists" btw: Vector is synchronized; ArrayList is not.
We cannot tell you why. Those who designed Java over two decades ago maybe can. It's not a useful question. Assuming you actually wanted to ask about java.util.Hashtable and not the fictional HashTable type, bear in mind that it's been obsolescent for nineteen years. Nineteen years! Don't use it. It (and Vector) have cruft that the replacement types, both synchronized and unsynchronized, do not carry. Use the modern (as of nineteen years ago) types.
I am wondering about how unsafe the use sun.misc.Unsafe actually is. I want to create a proxy of an object where I intercept every method call (but the one to Object.finalize for performance considerations). For this purpose, I googled a litle bit and came up with the following code snippet:
class MyClass {
private final String value;
MyClass() {
this.value = "called";
}
public void print() {
System.out.println(value);
}
}
#org.junit.Test
public void testConstructorTrespassing() throws Exception {
#SuppressWarnings("unchecked")
Constructor<MyClass> constructor = ReflectionFactory.getReflectionFactory()
.newConstructorForSerialization(MyClass.class, Object.class.getConstructor());
constructor.setAccessible(true);
assertNull(constructor.newInstance().print());
}
My consideration is:
Even though Java is advertised as Write once, run everywhere my reality as a developer looks rather like Write once, run once in a controllable customer's run time environment
sun.misc.Unsafe is considered to become part of the public API in Java 9
Many non-Oracle VMs also offer sun.misc.Unsafe since - I guess - there are quite some libraries already use it. This also makes the class unlikely to disappear
I am never going to run the application on Android, so this does not matter for me.
How many people are actually using non-Oracle VMs anyways?
I am still wondering: Are there other reasons why I should not use sun.misc.Unsafe I did not think of? If you google this questions, people rather answer an unspecified because its not safe but I do not really feel it is besides of the (very unlikely) possibility that the method will one day disappear form the Oracle VM.
I actually need to create an object without calling a constructor to overcome Java's type system. I am not considering sun.misc.Unsafe for performance reasons.
Additional information: I am using ReflectionFactory in the example for convenience which delegates to Unsafe eventually. I know about libraries like objenesis but looking at the code I found out that they basically do something similar but check for other ways when using Java versions which would not work for me anyways so I guess writing four lines is worth saving a dependency.
There are three significant (IMO) issues:
The methods in the Unsafe class have the ability to violate runtime type safety, and do other things that can lead to your JVM "hard crashing".
Virtually anything that you do using Unsafe could in theory be dependent on internal details of the JVM; i.e. details of how the JVM does things and represents things. These may be platform dependent, and may change from one version of Java to the next.
The methods you are using ... or even the class name itself ... may not be the same across different releases, platforms and vendors.
IMO, these amount to strong reasons not to do it ... but that is a matter of opinion.
Now if Unsafe becomes standardised / part of the standard Java API (e.g. in Java 9), then some of the above issues would be moot. But I think the risk of hard crashes if you make a mistake will always remain.
During one JavaOne 2013 session Mark Reinhold (the JDK architect) got a question: "how safe it is to use the Unsafe class?". He replied with sort of surprising answer: "I believe its should become a stable API. Of course properly guarded with security checks, etc..."
So it looks like there may be something like java.util.Unsafe for JDK9. Meanwhile using the existing class is relatively safe (as safe as doing something unsafe can be).
This question already has answers here:
Why is the String class declared final in Java?
(16 answers)
Closed 9 years ago.
I am new to Java and while I was reading through Java language I got into two doubts. Though I referred many websites and but still I am not very clear.
Why string class is immutable ? I saw some examples with new File(str) which leads to security threat, but I don't understand how if string is immutable, it will help this scenario.
Another doubt is why wait, notify and notifyall should be inside synchronized block. I know if not it throws illegalMonitorException. But I want to know the technical background why it should be in synchronized block and why not without in synchronized block wait and notify can have same behavior.
Why string class is immutable?
The question of why strings are immutable in Java is an old one, and it's been much debated. In my book, I'd say they are immutable because they should be immutable ;). That might sound like a cop out, but let me explain.
Most simply, strings are used all over the place, if they were mutable that would require a lot of baggage everywhere for making defensive copies and dealing with synchronization and so on. Making them immutable, and then having helpers for mutating them like StringBuilder/StringBuffer is a much better design choice (and a common choice in several languages, not just Java).
Second, everything should be immutable, unless there is a very good reason to justify mutability. Many many problems disappear with immutable classes (esp. pertaining to concurrency). See Effective Java: "Classes should be immutable unless there's a very good reason to make them mutable. If a class cannot be made immutable, limit its mutability as much as possible."
Third, strings are used in the internals of Java, such as the class loading mechanism. Making them immutable makes internal processes simpler, and prevents some security issues. (Another example, String constants are "interned" in Java for performance reasons: http://en.wikipedia.org/wiki/String_interning, and this is, again, much more sane with an immutable type.)
All in all there were probably several reasons the designers chose to make strings immutable in Java and as a day to day programmer it helps you out (as do the utils around creating new strings, like StringBuilder).
Why wait, notify and notifyall should be inside synchronized block?
Here's some info on that one: wait(), notify() and notifyAll() inside synchronized statement.
Basically it makes no sense for a thread to "notify" or "wait" unless it already owns the object's monitor.
In general though, if you are new to Java, you might want to also look at some of the newer utils relating to concurrency in java.util.concurrent: http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html. Often you can rely on these classes and avoid hand coding synchronization, which is notoriously difficult and error prone.
I have a requirement to lazy-load resources in a concurrent environment. The code to load the resources should be executed only once.
Both Double-checked locking (using JRE 5+ and the volatile keyword) and Initialization on demand holder idiom seems to fit the job well.
Just by looking at the code, Initialization on demand holder idiom seems cleaner and more efficient (but hey, I'm guessing here). Still, I will have to take care and document the pattern at every one of my Singletons. At least to me, It would be hard to understand why code was written like this on the spot...
My question here is: Which approach s is better? And why?
If your answer is none. How would you tackle this requirement in a Java SE environment?
Alternatives
Could I use CDI for this without imposing it's use over my entire project? Any articles out there?
To add another, perhaps cleaner, option. I suggest the enum variation:
What is the best approach for using an Enum as a singleton in Java?
As far as readability I would go with the initialization on demand holder. The double checked locking, I feel, is a dated and an ugly implementation.
Technically speaking, by choosing double checked locking you would always incur a volatile read on the field where as you can do normal reads with the initialization on demand holder idiom.
Initialisation-on-demand holder only works for a singleton, you can't have per-instance lazily loaded elements. Double-checked locking imposes a cognitive burden on everyone who has to look at the class, as it is easy to get wrong in subtle ways. We used to have all sorts of trouble with this until we encapsulated the pattern into utility class in our concurrency library
We have the following options:
Supplier<ExpensiveThing> t1 = new LazyReference<ExpensiveThing>() {
protected ExpensiveThing create() {
… // expensive initialisation
}
};
Supplier<ExpensiveThing> t2 = Lazy.supplier(new Supplier<ExpensiveThing>() {
public ExpensiveThing get() {
… // expensive initialisation
}
});
Both have identical semantics as far as the usage is concerned. The second form makes any references used by the inner supplier available to GC after initialisation. The second form also has support for timeouts with TTL/TTI strategies.
Initialization-on-demand holder is always best practice for implementing singleton pattern. It exploits the following features of the JVM very well.
Static nested classes are loaded only when called by name.
The class loading mechanism is by default concurrency protected. So when a thread initializes a class, the other threads wait for its completion.
Also, you don't have to use the synchronize keyword, it makes your program 100 times slower.
I suspect that the initialization on demand holder is marginally faster that double-checked locking (using a volatile). The reason is that the former has no synchronization overhead once the instance has been created, but the latter involves reading a volatile which (I think) entails a full memory read.
If performance is not a significant concern, then the synchronized getInstance() approach is the simplest.
This question already has answers here:
Closed 13 years ago.
In C++ we have the Resource Acquisition Is Initialization (RAII) pattern, which greatly simplifies resource management. The idea is to provide some wrapping object for any kind of resources. The wrapping object's destructor is then responsible for releasing the resources, when it goes out of its scope. For example:
{
auto_ptr<int> smartPointer = new int;
// some other code
} // the memory allocated for the int is released automatically
// by smartPointer's destructor
The most common usage are smart pointers. But, there are many other kinds of resources (files, mutexes, sockets, etc.) which can be managed exactly the same way.
In Java one doesn't have to bother the memory management. But all other types of resources remain. There is finally block, but its usage is quite inconvenient, especially when many different exceptions can be thrown.
So, my question is if there is any Java pattern which provides functionality equivalent to C++ RAII? If not, please share your best practices in this area (instead of the finally, unless it's used some sophisticated way).
You can use the usual acquire; try { use; } finally { release; }. Alternatively you can abstract the resource handling with the Execute Around idiom.
Joshua Bloch has proposed adding a mechanism called Automatic Resource Management to Java as part of Project Coin (small language changes for JDK 7):
The nearest equivalent is try/finally, see http://java.sun.com/docs/books/tutorial/essential/exceptions/finally.html
To many coders, the strength of the RAII idiom is that the life of the underlying resource is tied to a scope block, making things simpler to make and maintain; ultimately reducing errors from failing to release that resource.
Unfortunately you can't mimic this behaviour in Java as you can't create your own scope-bound structures. A language similar to Java that has tried to solve this problem is C#:
// explicit release
MyClass obj = MyClass();
obj.UseIt();
obj.Dispose();
// RAII-like (scope-bound) release
using(MyClass obj = new MyClass())
{
obj.UseIt();
}
Perhaps we'll see functionality like this implemented in future.