1.懒汉式
public class SingletonExample1{
private SingletonExample1(){}
private static SingletonExample1 instance= null;
public static SingletonExample1 getSingleton(){
if(instance == null){
instance = new SingletonExample1();
}
return instance;
}
}
2.饿汉式
public class SingletonExample2{
private SingletonExample2(){}
private static SingletonExample2 instance = new SingletonExample2();
public static SingletonExample2 getSingleton(){
return instance;
}
}
3. 懒汉式改进,加锁
public class SingletonExample3{
private SingletonExample3(){}
private static SingletonExample3 instance =null;
public static synchronized SingletonExample3 getSingleton(){
if(instance == null){
instance = new SingletonExample3();
}
return instance;
}
}
4. 懒汉式,双重校验锁
public class SingletonExample4{
private SingletonExample4(){}
private static SingletonExample4 instance = null;
public static SingletonExample4 getSingleton(){
if(instance== null){
synchronized(SingletonExample4.class){
if(instance== null){
instance = new SingletonExample4();
}
}
}
return instance;
}
}
5. 懒汉式+双重校验锁+volatile
public class SingletonExample5{
private SingletonExample5(){}
private static volatile SingletonExample5 instance= null;
public static SingletonExample5 getSingleton(){
if(instance==null){
synchronized(SingletonExample5 class){
if(instance==null){
instance = new SingletonExample5();
}
}
return instance;
}
}
}
6. 饿汉式采用静态代码块
public class SingletonExample6{
private SingletonExample6(){ }
private static SingletonExample6 instance = null;
static {
instance = SingletonExample6();
}
public static SingletonExample6 getSingleton(){
return instance;
}
}
前面已经写了6种,那有没有不会出现并发问题,同时又是推荐的写法呢?答案是有的。采用枚举的方式
7.采用枚举方式
public class SingletonExample7{
private SingletonExample7(){ }
private static getSingleton(){
return Singleton. INSTANCE. getInstance();
}
public enum Singleton(){
INSTANCE;
private static SingletonExample7 instance=null;
Singleton(){
instance = new SingletonExample7();
}
public SingletonExample7 getInstance(){
return instance;
}
}
}
同时单例模式使用的场景:
通常对于需要全局唯一的对象时,此时就需要考虑了。比如我们常用Spring中的ApplicationContext中getBean方法就是单例模式的。通常情况下,其首先会到缓存中去找,看有没有,采用的是饿汉式的方式,如果有的话,则直接加载,如果没有,首先创建,然后对其进行缓存,保证对象的唯一性。而XmlBeanFactory中getBean则是采用原型模式。