Review triggers thinking about the singleton mode and review triggers the example mode.

Source: Internet
Author: User

Review triggers thinking about the singleton mode and review triggers the example mode.

One situation found during code debuggingThat is to say, when I check the connection of memcached, I find that it is always around 100. Of course, this seems to be okay, because memcached has 1024 connections by default. But I want to see why there are 100, because my memcachedclient uses the singleton mode and I defined a memcachedClientFactory class. The main code is as follows:

Copy codeThe Code is as follows:
MemcachedClientFactory {
Private MemcachedConnectionBuilder memcachedConnectionBuilder;
Private String servers;
Private static MemcachedClient memcachedClient;

Private MemcachedClientFactory (){
}

Private MemcachedClientFactory (MemcachedConnectionBuilder memcachedConnectionBuilder, String servers ){
This. memcachedConnectionBuilder = memcachedConnectionBuilder;
This. servers = servers;
}

Public static MemcachedClient createClient (){
If (memcachedClient = null ){
This. memcahcedClien = new MemcachedClient (memcachedConnectionBuilder. build (), AddrUtil. get (servers ));
}
Return this. memcahcedClient;
}
}
}

Back to the initial question, why is there over 100 connections?

Can the above statement ensure that only one connection is generated? Obviously, no. Why? Multi-thread concurrency! The problem is that when multiple threads enter the createClient () method at the same time, and all of them are judged to be null for memcachedClient, multiple connections are generated. Haha, the problem is found.

Improvement:

Copy codeThe Code is as follows:
Public static synchronizd MemcachedClient createClient (){
If (memcachedClient = null ){
This. memcahcedClien = new
MemcachedClient (memcachedConnectionBuilder. build (), AddrUtil. get (servers ));
}
Return this. memcahcedClient;
}

In this way, the changes are simple. There is no problem with the program, and only one connection can be guaranteed.

However, aside from this problem, we can continue to think deeply about how to solve the concurrency problem in the singleton mode.

To sum up, there are three ways to solve the problem of single-instance mode concurrency:

1. Do not use delayed instantiation, but use advance instantiation.

That is, the program is rewritten:

Copy codeThe Code is as follows:
Public Class Singleton {
Private static Singleton instance = new Singleton ();
Private Singleton (){};

Public static Singleton getInstance (){
Return instance;
}
}

In this way, the jvm immediately creates the instance when loading the class. Therefore, the premise is that the instance creation is not a great burden, and I do not have to consider performance too much, and we confirm that this instance will be used. In fact, the code above can also be used in this way:

Copy codeThe Code is as follows:
MemcachedClientFactory {
Private MemcachedConnectionBuilder memcachedConnectionBuilder;
Private String servers;
Private static MemcachedClient memcachedClien = new
MemcachedClient (memcachedConnectionBuilder. build (), AddrUtil. get (servers ));

Private MemcachedClientFactory (){
}

Private MemcachedClientFactory (MemcachedConnectionBuilder memcachedConnectionBuilder, String servers ){
This. memcachedConnectionBuilder = memcachedConnectionBuilder;
This. servers = servers;
}

Public static MemcachedClient createClient (){
Return this. memcahcedClient;
}
}
}

However, it seems that there is no problem, but there is a risk that once someone accidentally calls the memcachedClient. shutdown () method, the whole program will not be able to regenerate the new memcachedClient. Of course this is an extreme situation, but to make the code robust, you can change it:

Copy codeThe Code is as follows:
Public static MemcachedClient createClient (){
If (memcachedClient = null ){
This. memcahcedClien = new MemcachedClient (memcachedConnectionBuilder. build (), AddrUtil. get (servers ));
}
Return this. memcahcedClient;
}

2. Use the synchronized keyword.

This can ensure synchronization, but we know that synchronized has a high overhead and will seriously affect the performance. Therefore, you must ensure that this method is not often called, or the overhead for creating this instance is not very large. Whether it can be improved, see the following.

3. Use "double check lock" to see how to use synchronization in getInstance

Copy codeThe Code is as follows:
Public Class Singleton {
Private volatile static Singleton instance;

Private Singleton (){};
Public static Singleton getInstance (){
If (instance = null ){
Synchronized (Singleton. class ){
If (instance = null ){
Instance = new Singleton ();
}
}

}
Return instance;
}
}

 

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.