最简单的设计模式----单例模式,你懂了吗?

1 饿汉模式

特点:类装载时就完成初始化,是比较简单而有效的单例模式
缺点:不一定会用到这个实例,浪费内存

public class Singleton01 {

    private static final Singleton01 INSTANCE01 =new Singleton01();

    private Singleton01(){}

    public static Singleton01 getInstance(){
        return INSTANCE01;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(()-> System.out.println(Singleton01.getInstance())).start();
        }
    }
}

2 懒汉模式

特点:类使用时才进行实例化
缺点:多线程下,存在线程安全问题

package singleton;

/**
 * @author yq
 */
public class Singleton02 {

    private static Singleton02 INSTANCE02;

    private Singleton02(){}

    public static Singleton02 getInstance() {
        if(INSTANCE02==null){
//            由于未加锁,多个线程都可以到达if内部,从而产生多个实例
//            模拟线程安全问题  sleep时间越长越容易看到效果          
//            try {
//                Thread.sleep(10);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
            INSTANCE02=new Singleton02();
        }
        return INSTANCE02;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(()-> System.out.println(Singleton02.getInstance().hashCode())).start();
        }
    }
}

3 双重校验锁

特点:双重校验保证大部分时间线程安全
缺点:不可以防止反序列化来获取多个实例

public class Singleton03 {
	//此处的volatile必须存在,否则会存在线程安全问题
    private static volatile Singleton03 INSTANCE03;

    private Singleton03(){}

    public static Singleton03 getInstance() {
    //A处:第一重判断,减少锁竞争
        if(INSTANCE03==null){
            synchronized (Singleton03.class){
            //B处:第二重判断,校验其他线程是否已经产生了实例,避免线程安全问题
                if(INSTANCE03==null){
                    INSTANCE03=new Singleton03();
                }
            }
        }
        return INSTANCE03;
    }

    public static void main(String[] args) {
        for (;;) {
            new Thread(()-> System.out.println(Singleton03.getInstance().hashCode())).start();
        }
    }
}

4 静态内部类

特点:比较完美的写法,但是对于需要传参的实例不友好,因为实例是在内部类创建的,外部传参很困难

public class Singleton04 {
    private Singleton04(){}
    
    private static class Holder{
        private final static Singleton04 INSTANCE =new Singleton04();
    }

    public static Singleton04 getInstance(){
        return Holder.INSTANCE;
    }
    
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(()-> System.out.println(Singleton04.getInstance().hashCode())).start();
        }
    }
}

5 枚举单例

特点:Effective Java 中推荐的单例写法,非常完美.可以保持单例,线程安全,还可以防止反序列化破解

public enum Singleton05 {
   
    INSTANCE;

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> System.out.println(INSTANCE.hashCode())).start();
        }
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值