java设计模式 ——单例模式

92 阅读2分钟

单例模式

饿汉式(线程安全)

package 单例模式;
​
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
​
/**
 * @author zwf
 * @Package: 单例模式
 * @ClassName: 懒汉式
 * @Description:
 * @date 2022/10/26 12:37
 */
public class 懒汉式 {
    public static void main(String[] args){
        Singleton instance = Singleton.getInstance();
        System.out.println(instance==Singleton.getInstance());
    }
}
//方式一
class Singleton{
    private static Singleton instance=new Singleton;
     //私有化构造器
    private Singleton(){
    }
    public static Singleton getInstance(){
       
        return instance;
    }
​
}
//方式二
class Singleton{
    private static Singleton instance;
     //私有化构造器
    private Singleton(){
    }
    //静态代码块
    static{
        instance=new Singleton();
    }
    public static Singleton getInstance(){
        return instance;
    }
​
}
​

说明:

该方式在成员位置声明Singleton类型的静态变量,并创建Singleton类的对象instance。instance对象是随着类的加载而创建的。如果该对象足够大的话,而一直没有使用就会造成内存的浪费。(线程安全)

懒汉式(线程不安全的)枚举实现线程安全

package 单例模式;
​
import com.sun.scenario.animation.shared.SingleLoopClipEnvelope;
​
/**
 * @author zwf
 * @Package: 单例模式
 * @ClassName: Singleton
 * @Description:
 * @date 2023/4/14 15:52
 */
public class Test {
    public static void main(String[] args) {
        Singleton instance = Singleton.SingletonEnum.INSTANCE.getInstance();
        
        instance.businessMethod();//我是一个单例!
        
        Singleton instance1 = Singleton.SingletonEnum.INSTANCE.getInstance();
        
        System.out.println(instance1==instance);true
    }
​
}
​
​
package 单例模式;
​
/**
 * @author zwf
 * @Package: 单例模式
 * @ClassName: Singleton
 * @Description: 静态枚举类
 * @date 2023/4/14 15:52
 */
public class Singleton {
    private Singleton(){
​
    }//私有构造器
    public void businessMethod(){
        System.out.println("我是一个单例!");
    }
    public static enum SingletonEnum{
        INSTANCE;
        private Singleton instance=null;
        private SingletonEnum(){
            int i=1;
            System.out.println("枚举构造器执行了"+i++);
            instance=new Singleton();
        }
        public Singleton getInstance(){
            return instance;
        }
​
    }
}

image-20230429100539965.png

双重检查锁(懒汉式)

package 单例模式;
​
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
​
/**
 * @author zwf
 * @Package: 单例模式
 * @ClassName: 双重检查锁
 * @Description:
 * @date 2022/10/26 14:41
 */
public class 双重检查锁 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
    }
}
class Singleton2{
    private volatile static Singleton2 instance; //volatile 可以保证jvm进行优化和指令重排序的有序性和可见性
    //私有化构造器
    private Singleton2(){
​
    }
    //双重检查锁
    public static Singleton2 getInstance(){
        if (instance==null){
            synchronized (Singleton2.class){
                if (instance==null){
                    instance=new Singleton2();
                }
            }
        }
        return instance;
    }
​
}
​
​

小结:

添加 volatile 关键字之后的双重检查锁模式是一种比较好的单例实现模式,能够保证在多线程的情况下线程安全也不会有性能问题。