单例模式的介绍和五种写法

1.介绍

单例模式,是23中设计模式中比较重要的设计模式,单例其实就是单一实例,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。

java中的RunTime类就使用了单例模式

2.写法

   1)饿汉式     

public class Singleton {
    /**
     * 1)构造器私有化
     * 2)自行创建,并且用静态变量保存
     * 3)对外提供这个实例
     * 4)强掉这是一个单例,我们可以用final修饰
     */
    public static final Singleton INSTANCE = new Singleton();
    private Singleton(){
    }
}

public class MainTest {
    public static void main(String[] args) {
        Singleton instance=Singleton.INSTANCE;
        Singleton instance1 = Singleton.INSTANCE;
        System.out.println(instance);
        System.out.println(instance1);
    }
}

//控制台输出
cn.nlg.test.Singleton@1540e19d
cn.nlg.test.Singleton@1540e19d

  特点:

       a)在这个类初始化时就创建了对象, 每次调用都返回同一个对象

       b)如果没有使用到这个对象会浪费内存空间

   2)懒汉式

public class Singleton {

    private static Singleton instance = null;

    private Singleton() {
    }
    
    //这里多线程环境下会有线程安全问题,单线程没问题
    public static Singleton getInstance() {
        if(instance == null){
            instance =new Singleton();
        }
        return instance;
    }

}

public class MainTest {
    public static void main(String[] args) {
        Singleton instance=Singleton.getInstance();
        Singleton instance1 = Singleton.getInstance();
        System.out.println(instance);
        System.out.println(instance1);
    }
}

//控制台输出
cn.nlg.test.Singleton@1540e19d
cn.nlg.test.Singleton@1540e19d




特点:  多线程的环境下会存在线程安全问题这个适用于单线程

   3)双检锁

class Singleton {
    public volatile  static Singleton  instance = null;

    public Singleton(){ }


    public static Singleton getInstance(){
        //外层判断是为了让instance不为空时无需等待
        if(instance == null){
        //使用synchronized关键字,保证了每次只有一个线程操作
            synchronized (Singleton.class){
                if(instance == null){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }

}
//主方法测试
public class MainTest {
    public static void main(String[] args) {
        Singleton instance=Singleton.getInstance();
        Singleton instance1 = Singleton.getInstance();
        System.out.println(instance);
        System.out.println(instance1);
    }
}
//控制台输出
cn.nlg.test.Singleton@1540e19d
cn.nlg.test.Singleton@1540e19d

 特点:1)解决了线程安全问题

            b)volatile是为了防止指令重排,可以去了解一下volatile关键字的作用

   4)静态内部类     

public class Singleton{
    private Singleton(){}
    //静态内部类
    private static class Inner{
        private static Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance(){
        return Inner.INSTANCE;
    }
}

//主方法测试
public class MainTest {
    public static void main(String[] args) {
        Singleton instance=Singleton.getInstance();
        Singleton instance1 = Singleton.getInstance();
        System.out.println(instance);
        System.out.println(instance1);
    }
}
//控制台输出
cn.nlg.test.Singleton@1540e19d
cn.nlg.test.Singleton@1540e19d

  特点:a)这是懒汉式中比较推荐的写法

             b)外部类加载时并不需要立即加载内部类,内部类不被加载则不去初始化INSTANCE

   5)枚举

public enum Singleton {
    INSTANCE;
}
//主方法测试
public class MainTest {
    public static void main(String[] args) {
        Singleton instance=Singleton.INSTANCE;
        Singleton instance1 =Singleton.INSTANCE;
        System.out.println(instance);
        System.out.println(instance1);
    }
}
重写了toString方法,控制台输出
INSTANCE
INSTANCE

  特点 :a) enum 类型是线程安全的,因为Java 类的加载和初始化过程都是线程安全的(反编译一下枚举类)

              b)饿汉式中比较推荐的写法

   例子:

      枚举类:

public enum T {
	SPRING,SUMMER,AUTUMN,WINTER;
}

    反编译之后的枚举类:

public final class T extends Enum 
{
	//省略部分内容
	public static final T SPRING;
	public static final T SUMMER;
	public static final T AUTUMN;
	public static final T WINTER;
	private static final T ENUM$VALUES[];枚举类型和泛型 < 228
	static
	{
		SPRING = new T("SPRING", 0);
		SUMMER = new T("SUMMER", 1);
		AUTUMN = new T("AUTUMN", 2);
		WINTER = new T("WINTER", 3);
		ENUM$VALUES = (new T[] {
		SPRING, SUMMER, AUTUMN, WINTER
	});
	}
}

1.枚举类型T不可被继承
2.T中所有属性都被 static final 修饰

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值