Java单例模式的写法

1、常规写法

public class Singleton {
    private static Singleton singleton = null;
    private Singleton(){}
    public static Singleton getSingleton() {
        if(singleton == null) singleton = new Singleton();
        return singleton;
    }
}

这种方法可以实现延时加载,但是有一个致命弱点:线程不安全。如果有两条线程同时调用getSingleton()方法,就有很大可能导致重复创建对象。


2、添加线程安全

public class Singleton {
    private static volatile Singleton singleton = null;
 
    private Singleton(){}
 
    public static Singleton getSingleton(){
        synchronized (Singleton.class){
            if(singleton == null){
                singleton = new Singleton();
            }
        }
        return singleton;
    }    
}

对创建单例模式的资源设置同步锁,注意关键字volaitile是必需的,volatile禁止指令重排序优化。多线程代码由于编译器优化,在实际执行的时候可能与我们编写的顺序不同。编译器只保证程序执行结果与源代码相同,却不保证实际指令的顺序与源代码相同。这在单线程看起来没什么问题,然而一旦引入多线程,这种乱序就可能导致严重问题。volatile关键字就可以从语义上解决这个问题。

volatile在JDK1.5引入


3、静态内部类的写法

public class Singleton {
    private static class Holder {
        private static Singleton singleton = new Singleton();
    }
     
    private Singleton(){}
         
    public static Singleton getSingleton(){
        return Holder.singleton;
    }
}


本质还是一样的,由于静态内部类只会被加载一次,所以这种写法也是线程安全的。



网上还有枚举类的写法,大家可以搜索一下。




你可能感兴趣的:(java,多线程,Singleton,对象,线程安全)