设计模式--单例模式

目录

 

什么是单例,单例有什么作用

代码展示

 源码使用地址

总结


什么是单例,单例有什么作用

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

代码展示

单例创建的方式有八种:

  1. 饥汉式两种 : 静态变量单例,静态代码块单例
  2. 懒汉式四种 : 懒汉式(线程不安全单例),懒汉式(线程安全,同步方法单例),懒汉式(线程安全,同步代码块),懒汉式(线程安全,双重检测)
  3. 静态内部类单例
  4. 枚举单例

静态变量单例:

/**
 * 饿汉式(静态变量)
 * 好处:
 *      写法简单,比较方便,再类加载的时候就完成了装载,避免了同步问题
 * 坏处:
 *      再类加载的时候就会完成装载,达不到延迟加载的效果,如果这个类一直没有使用,就会造成内存的浪费
 * 总结:
 *      可以使用这种方式,但是有可能造成内存的浪费
 */
public class Singleton {
    //私有化构造器,防止外部new
    private Singleton(){
    }
    // 内部创建对象实例
    private final static Singleton singleton = new Singleton();

    // 设置公用方法获取对象
    public static Singleton getInstance(){
        return singleton;
    }
}

静态代码块单例:

/**
 * 饿汉式(静态代码块)
 * 好处:
 * 写法简单,比较方便,再类加载的时候就完成了装载,避免了同步问题
 * 坏处:
 * 再类加载的时候就会完成装载,达不到延迟加载的效果,如果这个类一直没有使用,就会造成内存的浪费
 * 总结:
 * 可以使用这种方式,但是有可能造成内存的浪费
 */
public class Singleton1 {
    //私有化构造器,防止外部new
    private Singleton1() {
    }

    // 内部创建对象实例
    private static Singleton1 singleton;

    static {
        singleton = new Singleton1();
    }

    // 设置公用方法获取对象
    public static Singleton1 getInstance() {
        return singleton;
    }
}

 懒汉式(线程不安全单例):

/**
 * 懒汉式(线程不安全)
 * 好处:
 * 可以达到延迟加载,但是只能再单线程的情况使用
 * 坏处:
 * 再多线程的情况下,如果有3个线程abc   a进入了if判断对象是否存在还没有结束的时候,b也进去了,那么就会创建多个对象,就不是单例模式了
 * 总结:
 * 可以达到延迟加载的效果,但是线程不安全,不建议再实际项目中使用
 */
public class Singleton2 {
    //私有化构造器,防止外部new
    private Singleton2() {
    }

    // 内部创建对象实例
    private static Singleton2 singleton;

    // 设置公用方法获取对象
    public static Singleton2 getInstance() {
        if (null ==singleton){
            singleton = new Singleton2();
        }
        return singleton;
    }
}

 懒汉式(线程安全,同步方法单例):

/**
 * 懒汉式(线程安全,同步方法)
 * 好处:
 * 可以达到延迟加载,解决了线程问题
 * 坏处:
 * 如果多个线程执行这个方法就会造成,一个对象多个线程来调用判断这样会影响效率
 * 总结:
 * 可以达到延迟加载的效果,但是影响效率,不建议再实际项目中使用
 */
public class Singleton3 {
    //私有化构造器,防止外部new
    private Singleton3() {
    }

    // 内部创建对象实例
    private static Singleton3 singleton;

    // 设置公用方法获取对象 添加同步代码 确保方法有对象执行的时候,其他操作不能执行
    public static synchronized Singleton3 getInstance() {
        if (null ==singleton){
             singleton = new Singleton3();
        }
        return singleton;
    }
}

 懒汉式(线程安全,同步代码块):

/**
 * 懒汉式(线程安全,同步代码块)
 * 好处:
 * 可以达到延迟加载,但是只能再单线程的情况使用
 * 坏处:
 * 再多线程的情况下,如果有3个线程abc   a进入了if判断对象是否存在还没有结束的时候,b也进去了,那么就会创建多个对象,就不是单例模式了
 * 总结:
 * 可以达到延迟加载的效果,线程安全,但是只能再单线程的情况使用,不建议再实际项目中使用
 */
public class Singleton4 {
    //私有化构造器,防止外部new
    private Singleton4() {
    }

    // 内部创建对象实例
    private static Singleton4 singleton;

    // 设置公用方法获取对象 添加同步方法 确保方法有对象执行的时候,其他操作不能执行
    public static Singleton4 getInstance() {
        if (null == singleton) {
            synchronized (Singleton4.class) {
                 singleton = new Singleton4();
            }
        }
        return singleton;
    }
}

懒汉式(线程安全,双重检测):

/**
 * 懒汉式(线程安全,双重检测)
 * 好处:
 * 可以达到延迟加载,线程安全,效率高
 * 总结:
 * 可以达到延迟加载的效果,线程安全,建议再实际项目中使用
 */
public class Singleton5 {
    //私有化构造器,防止外部new
    private Singleton5() {
    }

    // 内部创建对象实例
    //volatile
    //1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
    //2)禁止进行指令重排序。
    private static volatile Singleton5 singleton;

    // 设置公用方法获取对象 添加同步方法 确保方法有对象执行的时候,其他操作不能执行
    public static Singleton5 getInstance() {
        if (null == singleton) {
            synchronized (Singleton5.class) {
                if (null == singleton) {
                     singleton = new Singleton5();
                }
            }
        }
        return singleton;
    }
}

 静态内部类单例:

/**
 * 静态类内部类
 * 好处:
 * 通过静态内部类加载,做到了延迟加载的效果,同时保证了线程的安全,效率比较高,代码比较简洁
 * 总结:
 * 推荐使用
 */
public class Singleton6 {
    //私有化构造器,防止外部new
    private Singleton6() {
    }
    // 静态内部类
    private static class Singleton6Instanse{
        private static final Singleton6 SINGLETON_6 = new Singleton6();
    }
    // 公用获取对象实例
    public static Singleton6 getInstance(){
        return Singleton6Instanse.SINGLETON_6;
    }

}

枚举单例:

/**
 * 枚举
 * 好处:
 * 线程安全,还能防止反序列化 ,Effective java || josh Bloch 作者推荐使用的
 * 总结:
 * 推荐使用
 */
public enum Singleton7 {
    INSTANCE;
    public void getInstance(){
        System.out.println("我是枚举单例");
    }
}

 源码使用地址

JDK 中 Runtime 使用的就是饥汉式静态变量单例

总结

/**
 * 单例模式
 * 总结:
 * 创建单例模式的方法有八种 Singleton,Singleton1,Singleton2,Singleton3,Singleton4
 * 推荐使用三种 Singleton5,Singleton6,Singleton7
 * 使用的场景:需要频繁的进行创建和销毁的对象,创建时耗时过多的或者消耗资源过多的的对象,经常使用的    
 * 工具对象,频繁访问数据库或文件的
 * 的对象(数据源,sessionFactory)
 */

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值