Java设计模式-单例模式

1、简单介绍

单例模式是一种创建型设计模式, 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。
在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例

2、单例模式特点

1.单例类只有一个实例

2.单例类必须自己创建自己得唯一实例

3.单例类必须给所有其他对象提供这一实例
3、分类
饿汉式,懒汉式,双重检测锁式,静态内部类式,枚举类单例等,只要常见得是前三种

饿汉模式
解释:饿汉模式,实例在初始化得时候就创建好,不管你用不用
优点:线程安全,在类加载得同时创建好一个静态类
缺点:占一定内存,消耗资源
代码:


/**
 * @Author charles.yao
 * @Description 饿汉式单例模式
 * @Date 2023/2/23 18:50
 */
public class HungerySingleton {
    //私有实例,静态变量在类加载得时候进行初始化,线程安全
    private static final HungerySingleton INSTANCE = new HungerySingleton();

    public HungerySingleton() {
    }

    /**
     * 获取实例得方法-静态工厂方法
     *
     * @return
     */
    public static HungerySingleton getInstance() {
        return INSTANCE;
    }
}


/**
 * @Author charles.yao
 * @Description 饿汉测试类
 * @Date 2023/2/23 18:52
 */
public class HungeryTest {
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            System.out.println("饿汉创建实例" + HungerySingleton.getInstance());
        }
    }
}

懒汉模式(线程不安全方式)
解释:懒汉模式,只有在用的时候才去检查有没有实例,有直接返回,没有创建实例
优点:起到懒加载模式,不占用资源,
缺点:在多线程模式下,会有线程安全问题,if (lazySingelton1 == null),会产生多个实例,

/**
 * @Author charles.yao
 * @Description 懒汉模式第一种
 * @Date 2023/2/23 19:00
 */
public class LazySingelton1 {
    public LazySingelton1() {

    }

    private static LazySingelton1 lazySingelton1 = null;

    public static LazySingelton1 getInstance() {
        if (lazySingelton1 == null) {
            lazySingelton1 = new LazySingelton1();
        }
        return lazySingelton1;
    }
}


/**
 * @Author charles.yao
 * @Description 懒汉模式测试类
 * @Date 2023/2/23 19:02
 */
public class LazySIngleTest {
    public static void main(String[] args) {

        for (int i = 0; i < 100; i++) {
          new Thread(()->{
              System.out.println(LazySingelton1.getInstance());
          }).start();

        }
    }
}

测试结果显示产生多个实例

com.yyh.designpattern.singetonPattern.lazy.LazySingelton1@371adbca
com.yyh.designpattern.singetonPattern.lazy.LazySingelton1@371adbca
com.yyh.designpattern.singetonPattern.lazy.LazySingelton1@371adbca
com.yyh.designpattern.singetonPattern.lazy.LazySingelton1@371adbcc

懒汉模式(线程安全方式)

方法加锁,使用synchronized,解决线程安全问题,但是每次调动都加锁,效率低


/**
 * @Author charles.yao
 * @Description 懒汉模式第2种-线程安全模式
 * @Date 2023/2/23 19:00
 */
public class LazySingelton2 {
    public LazySingelton2() {

    }

    private static LazySingelton2 lazySingelton1 = null;

    public static synchronized LazySingelton2 getInstance() {
        if (lazySingelton1 == null) {
            lazySingelton1 = new LazySingelton2();
        }
        return lazySingelton1;
    }
}

懒汉模式(双重检锁模式)

进入getInstance方法时先不同步,进入方法过后,先检查实例是否存在,如果存在则直接返回,如果不存在才进入synchronized修饰的同步代码块,进入后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例。即保证了懒加载,又保证了高性能。推荐使用。

双重检查加锁机制的实现使用到一个关键字volatile:被volatile修饰的变量的值,保证了多个线程之间的可见性。即被一个线程修改后,其他线程立即可见。


/**
 * @Author charles.yao
 * @Description 懒汉模式第3种--双重检查锁定-线程安全,性能较低
 * @Date 2023/2/23 19:00
 */
public class LazySingelton3 {
    public LazySingelton3() {

    }

    private static volatile LazySingelton3 lazySingelton1 = null;

    public static synchronized LazySingelton3 getInstance() {
         //第一个 if 语句用来避免 uniqueInstance 已经被实例化之后的加锁操作
        if (lazySingelton1 == null) {
            synchronized (LazySingelton3.class) {
                //第二个 if 语句进行了加锁,所以只能有一个线程进入,就不会出现 instance == null 时两个线程同时进行实例化操作。
                if (lazySingelton1 == null)
                    lazySingelton1 = new LazySingelton3();
            }
        }
        return lazySingelton1;
    }
}

静态内部类

线程安全但是破坏了反射


/**
 * @Author charles.yao
 * @Description 静态内部类单例模式-线程安全可能会破坏反射
 * @Date 2023/2/23 19:22
 */
public class StaticInnerClassSingleton {
    //静态内部类
    private static class LoadingClass {
        private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton();
    }

    /**
     * 生成方法
     *
     * @return
     */
    public static StaticInnerClassSingleton getInstance() {
        return LoadingClass.INSTANCE;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值