I have seen many single-piece ModelsArticleThere are more books on the Internet. In general, only how to implement the single-piece mode does not introduce the use of the single-piece mode, nor does it introduce the single-piece mode. The single-piece mode does not seem to cause logical problems. However, it just seems.
Before describing my problems, let me explain my understanding of the principles.
First, the single-piece mode is a self-created object, and it is always unique during runtime. Aside from anything that can be self-created, how can we maintain a unique object to understand? Let's take a look at a common class:
Package Singleton;
Public ClassSimpleclass {
}
Perform a unit test on it:
Simpleclass S3 = New Simpleclass ();
Simpleclass S4 = New Simpleclass ();
Assert. assertnotsame (S3, S4 );
This test is always correct. S3 and S4 are of the same type but not the same. Simpleclass can be an apple, but S3 and S4 are specific apple. No two leaves are identical in the world, but they are all leaves.
For platforms with garbage collection mechanisms such as. NET and Java, S3 and S4 are put in two places of heap. It can be described in Figure 1. Both S3 and S4 have their own independence.
Figure 1
What is the result of the single-piece mode? The single-piece Mode means that both S3 and S4 point to the address 001144. The result is that they are of the same type and the same thing. It can be understood that the giant pandas are almost extinct (to protect the giant pandas, hey, poor Dao like the giant pandas). The world is just a giant panda. So everyone went to visit it. In the eyes of everyone, there is one giant panda, and all the photos taken are recorded in the same giant panda.
Basic single-piece ModeCodeIs:
Package Singleton;
/**
* @ Author Birdshover
* @ URL http://birdshover.cnblogs.com
*/
Public Class Singletonclass {
Private Singletonclass (){
}
Private Static Singletonclass instance;
/**
* @ Return
*/
Public Static Singletonclass getinstance (){
If (Instance = Null ){
Synchronized (Singletonclass. Class ){
If (Instance = Null ){
Instance = New Singletonclass ();
}
}
}
Return Instance;
}
}
Perform a unit test on it: Singletonclass S1 = Singletonclass. getinstance ();
Singletonclass S2 = Singletonclass. getinstance ();
Assert. assertsame (S1, S2 );
The results are as expected.
The problem now is that no matter who gets the singletonclass instance, it is the same thing, so singletonclass is equivalent to being static.
Assume that I have a class A and A has a static field B.
Class {
Static B = new B ();
}
Class B {
Private int F;
Public void W () {f ++ ;}
}
I assume that there is no assignment to B elsewhere, so B is also a single piece in the system. Of course, it is not a single-piece mode. The number of object A is not fixed. Therefore, although the range of the N-plus instance of a to method W of Method B is safe, if field F is contained in field B, W has a value assignment operation on F. Is there a problem?
That is to say, if B is in a state, it will cause trouble. Imagine that two painters are preparing to change their colors. If two painters queue up to operate, then after the first painter completes the operation, he can tell everyone that the painting is blue now. After modification, the second painter can say that the painting is red. If the two painters draw together, the first one is finished, and the second one is painting. When the first painter declared that the painting was blue, we saw that the painting was blue and red, both of which were available. This is the trap of the singleton mode. To show this trap, the singletonclass code is modified:
Package Singleton;
/**
* @ Author Birdshover
* @ URL http://birdshover.cnblogs.com
*/
Public Class Singletonclass {
Private Singletonclass (){
}
Private Static Singletonclass instance;
/**
* @ Return
*/
Public Static Singletonclass getinstance (){
If (Instance = Null ){
Synchronized (Singletonclass. Class ){
If (Instance = Null ){
Instance = New Singletonclass ();
}
}
}
Return Instance;
}
Private Int Value;
Public Void Raise (){
For ( Int I = 0 ; I < 10 ; I ++ ){
Value ++ ;
System. Out. println ( " Thread: " + Thread. currentthread (). GETID ());
}
}
/**
* @ Return
*/
Public Int Getvalue (){
Return Value;
}
/**
*@ ParamValue the value to set
*/
Public VoidSetvalue (IntValue ){
This. Value=Value;
}
}
Prepare the unit test code for multithreading testing:
Package Unittest. Singleton;
ImportJava. util. Random;
ImportSingleton. simpleclass;
ImportSingleton. singletonclass;
ImportJUnit. Framework. Assert;
ImportJUnit. Framework. testcase;
Public ClassSingletonclasstestExtendsTestcase {
Static FinalRandom R=NewRandom ();
Public Void Testthread () Throws Interruptedexception {
For ( Int I = 0 ; I < 100 ; I ++ ){
Thread thread = New Thread ( New Mythread ());
Thread. Start ();
}
Thread. currentthread (). Sleep ( 2000 );
Singletonclass S1 = Singletonclass. getinstance ();
System. Out. println (s1.getvalue ());
}
Private Class Mythread Implements Runnable
{
Public Void Run (){
Singletonclass S1 = Singletonclass. getinstance ();
S1.raise ();
System. Out. println ( " Value: " + S1.getvalue ());
}
}
}
What happened after the test is complete? I want to extract the parts of the previous data group:
Thread: 8
Thread: 8
Thread: 8
Thread: 8
Thread: 8
Thread: 8
Thread: 8
Thread: 8
Thread: 8
Thread: 8
Value: 10
The results show that sometimes only one thread is running (my single-core CPU), and the value is correct.
Thread: 12
Thread: 13
Thread: 14
Thread: 15
Thread: 16
Thread: 17
Thread: 18
Thread: 19
Thread: 20
Thread: 22
Thread: 21
Thread: 23
Thread: 24
The results show that the thread execution sequence is starting to be chaotic.
Value: 1000
Value: 1000
Value: 1000
Value: 1000
Value: 1000
These results indicate that the data obtained by the following threads is the same, which may lead to expected deviations and logical errors.
The trap of the single-piece mode is described here. I went to the Internet and read it for a moment. Most articles focus on the case of building a single-piece mode without talking about the website instance. The terrylee article described a complete example, but did not describe this problem.