Java Single example and the thought of a single case __java

Source: Internet
Author: User
Tags static class visibility volatile
thinking from Java single example and single case

Objective

A few days ago accidentally saw an article, talked about the cliché of a single example, holding a review of the mentality points in, or those familiar with the content, but found himself thinking of the angle changed, before more is to remember, only stay on the surface, and now more is to think why would do so. So today I'm going to summarize the common examples in Java and write down my own thoughts. 2 text

Some of the common types of examples in Java:

A hungry man-type single case

Double check lock single case

Static internal class Single example

Enum Single Example

Let's break it down: 3 A Hungry man-type single case

public class Singleton {

Private Singleton () {}

Private static final Singleton instance = new Singleton ();

public static Singleton getinstance () {return instance;

} }

The initialization of a instance in a a hungry man is done when the class is loaded, and the load of the class is performed by ClassLoader, which is guaranteed by the JVM to be synchronized, so it is inherently thread-safe. Its drawbacks are obvious: it is easy to waste resources and can cause performance problems if too many of the construction methods are handled. 4 Double check Lock single case

public class Singleton {

Private static volatile Singleton instance;

Private Singleton () {}

public static Singleton getinstance () {

if (instance = = null) {

Synchronized (Singleton.class) {

if (instance = = null) {instance = new Singleton ();    }} return instance; } }

This is the perfect version of evolution to the final, it has a lot of advantages, we have to analyze one by one:

Deferred loading, whose instance is created the first time it is used

Thread-safe, using synchronized to resolve thread synchronization issues

Performance improvement, if only one check, is equivalent to solve the 1% probability of synchronization problem, and the use of a 100% appearance of the shield. Double check is the chance that 100% of the shields that appear will be changed to 1%. Only when instance is null does it enter the code snippet of synchronized-dramatically reducing the probability.

Here we have to mention the volatile keyword, volatile main role has two points:

Memory Visibility: Visibility means that when a thread modifies a shared variable, another thread can read the modified value.

Prohibit command rearrangement: This is what is used in the double check lock single case.

So what is the command rearrangement? Instruction rearrangement refers to the computer in order to improve the efficiency of execution, will do some optimization, without affecting the final results of the case, may be the order of the execution of some statements to adjust.

Here's an example of a programmer's home about a program error caused by a rearrangement of instructions, written very clearly:

Mainly in the instance = new Singleton (), this is not an atomic operation, in fact in the JVM this sentence probably did the following 3 things.

allocating memory to instance

Call the Singleton constructor to initialize the member variable to form an instance

Point the instance object to the allocated memory space (instance is not NULL to perform this step)

However, there is an optimization of instruction reordering in the JVM's Just-in-time compiler. In other words, the order of the second and third steps above is not guaranteed, and the final order of execution may be 1-2-3 or 1-3-2. If it is the latter, then the 3 execution, 2 is not executed before the thread two preemption, then instance has been non-null (but not initialized), so thread two will return directly to instance, and then use, and then logically to the error.

To explain a little bit more, that is, because there is an intermediate state where "instance is no longer null but not yet initialized", and this time, if there are other threads just running to the first layer if (instance = null) Here, read the instance has not been null, so directly to the middle State of the instance to use, it will produce problems.
The key here is that the thread T1 the instance write operation, and the thread T2 performs the read operation.

After the instance is declared as volatile, the write operation will have a memory barrier so that it does not have to invoke the read operation until its assignment is complete.

Note: The volatile block does not instance the instructions in [1-2-3] inside the phrase "new Singleton ()", but ensures that the read operation (if (1-2-3 = null) is not invoked until a write operation ([instance]) completes. 5 Static Internal Class single example

public class Singleton {

Private Singleton () {}

private Static Class Innerclass {

private static final Singleton INSTANCE = new Singleton ();

}

public static Singleton getinstance () {

return innerclass.instance; } }

Since Innerclass is an internal class that is used only in the Singleton getinstance () of the outer class, the time it is loaded is when the getinstance () method is first invoked. And the Innerclass is initialized by ClassLoader to ensure synchronization. 6 Some personal thinking

When I first saw this type of writing, I can not help but marvel at its ingenious, both the use of ClassLoader to ensure synchronization, and the implementation of delayed loading, simply gadget its technology. But a few days ago when I realized this kind of writing, it produced some thinking, why must use static internal class to achieve it, with non-static internal class can not do it.
The answer, of course, is no, but what is the reason? At first I thought that only static internal classes would be loaded on the first call, which was not true, and that internal classes (both static and non-static) would be loaded the first time they were called.
Later, I directly removed the static key before the internal class, compiler error Inner classes cannot have static declarations (internal class can not hold static declaration), this is why.

We know that to use a static member of a class, you need to load the class into a virtual machine, and members ' inner classes need to be used by an instance of the external class object, which is not required by static members. So Java does not allow non-static internal classes to hold static declarations. 7 Enum Single Example

public enum Singleton {

INSTANCE;

public void Func1 () {

Do something}}

The enumeration provides an automatic serialization mechanism to prevent the creation of new objects when deserializing, in addition to thread safety and preventing reflection from forcing calls to the construction method. Therefore, effective Java recommends using single element enumerations as much as possible to implement a single example. 8 Some personal thinking

How do enumerated cases prevent reflection attacks?
We have to consider the implementation of the enumeration.
The above enumerated class is compiled to be the following format:

Public abstract class Singleton extends Enum

Class is abstract, so it cannot be instantiated, and reflection is powerless. 9 Conclusion

More and more feel that their grasp of the foundation is not enough, it seems to be time to take the Java Foundation well over again.

Author: instance Wave
Link: https://www.jianshu.com/p/64cad6e0f5ba
Objective

A few days ago accidentally saw an article, talked about the cliché of a single example, holding a review of the mentality points in, or those familiar with the content, but found himself thinking of the angle changed, before more is to remember, only stay on the surface, and now more is to think why would do so. So today I'm going to summarize the common examples in Java and write down my own thoughts. 2 text

Some of the common types of examples in Java:

A hungry man-type single case

Double check lock single case

Static internal class Single example

Enum Single Example

Let's break it down: 3 A Hungry man-type single case

public class Singleton {

Private Singleton () {}

Private static final Singleton instance = new Singleton ();

public static Singleton getinstance () {return instance;

} }

The initialization of a instance in a a hungry man is done when the class is loaded, and the load of the class is performed by ClassLoader, which is guaranteed by the JVM to be synchronized, so it is inherently thread-safe. Its drawbacks are obvious: it is easy to waste resources and can cause performance problems if too many of the construction methods are handled. 4 Double check Lock single case

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.