单例模式

单例模式的基础概念

单例模式是什么

在整个系统的运行过程中,一个类只能拥有一个实例供全局使用;

单例模式使用场景
  1. 共享某个资源,例如:配置文件、日志文件、数据库连接池、驱动、缓存等
  2. 全局工具类,例如:计数器、唯一序列号、md5等
  3. java核心类,例如:java.lang.Runtime,java.awt.Desktop

单例模式代码编写

满足满足的两点要求
  1. 在JVM中,只能存在唯一实例
  2. 必须提供全局可以访问的点
饿汉模式
源代码
package singleton;

/**
 * @author :  freedom
 * @Description :  饿汉式单例模式即类加载立即创建对象,不用等到使用时才创建
 * @Creation Date:  2019-11-21 8:01 上午
 */
public class SimpleSingleton {

  /**
   * 声明一个私有的不可更改的单例实例
   */
  private static final SimpleSingleton simpleSingleton = new SimpleSingleton();

  /**
   * 私有化默认构造方法,不允许外部调用
   */
  private SimpleSingleton() {
  }

  /**
   * 通过静态方法获取实例
   */
  public static SimpleSingleton getInstance() {
    return simpleSingleton;
  }

}

说明

饿汉模式即只要类加载,就创建唯一实例,不管用不用的上。
优点:线程安全,实现简单
缺点:不使用也创建,浪费内存

懒汉模式
源代码
package singleton;

/**
 * @author :  freedom
 * @Description :  懒汉单例模式即只有在调用时才被实例化
 * @Creation Date:  2019-11-21 8:21 上午
 */
public class LazySingleton {

  /**
   * 私有化静态对象实例
   */
  private static LazySingleton lazySingleton = null;

  /**
   * 私有化构造方法
   */
  private LazySingleton() {
  }

  /**
   * 判断实例是否为空时,创建实例对象。只有在调用getInstance()方法时,才会创建单例对象。 此方法单线程是安全的,多线程不安全;多个线程同时调用会创建多个不同的单例
   *
   * @return 单例对象
   */
  public static LazySingleton getInstance() {
    if (lazySingleton == null) {
      lazySingleton = new LazySingleton();
    }
    return lazySingleton;
  }

  //======================华丽的分割线===========================
  //以下是多线程调用时,解决线程不安全问题

  /**
   * 采用方法加锁方式解决
   */
  public static synchronized LazySingleton getInstance1() {
    if (lazySingleton == null) {
      lazySingleton = new LazySingleton();
    }
    return lazySingleton;
  }

  /**
   * 采用synchronized块解决线程安全问题,但是此种方式还是存在两个或者多个线程同时进入if里的问题
   */
  public static LazySingleton getInstance2() {
    if (lazySingleton == null) {
      synchronized (LazySingleton.class) {

        lazySingleton = new LazySingleton();
      }

    }
    return lazySingleton;
  }

  /**
   * 采用双重验证方式解决线程不安全的问题
   */
  public static LazySingleton getInstance3() {
    if (lazySingleton == null) {
      synchronized (LazySingleton.class) {
        if (lazySingleton == null) {
          lazySingleton = new LazySingleton();
        }
      }
    }
    return lazySingleton;
  }
}

说明

懒汉模式:唯一实例在被调用时才创建
优点:只在被掉用时才初始化,单线程是安全的
缺点:多线程不安全,解决线程不安全问题,会降低执行效率

静态内部类单例模式
源代码
package singleton;

/**
 * @author :  freedom
 * @Description :  线程安全的单例模式类(即满足使用时才加载也满足线程安全)
 * @Creation Date:  2019-11-21 12:35 下午
 */
public class ThreadSafeSingleton {

  /**
   * 私有化默认的构造方法
   */
  private ThreadSafeSingleton() {
  }

  /**
   * 静态内部类
   */
  public static class SingletonHelper {

    /**
     * 私有化静态内部类的属性
     */
    private static final ThreadSafeSingleton threadSafeSingleton = new ThreadSafeSingleton();
  }

  /**
   * 提供全局访问的静态方法
   */
  public static ThreadSafeSingleton getInstance() {
    return SingletonHelper.threadSafeSingleton;
  }

}

说明

静态内部类单例模式:只有被调用时才被创建唯一实例,并且多线程安全。单例模式推荐写法。

测试类
源代码
package singleton;

/**
 * @author :  freedom
 * @Description :  单例模式测试类
 * @Creation Date:  2019-11-21 8:06 上午
 */
public class SingletonTest {

  public static void main(String[] args) {
//    SimpleSingleton simpleSingleton1=SimpleSingleton.getInstance();
//    SimpleSingleton simpleSingleton2=SimpleSingleton.getInstance();
//    if(simpleSingleton1.hashCode()==simpleSingleton2.hashCode()){
//      System.out.printf("获取到的两个实例是同一个实例");
//    }else{
//      System.out.printf("获取到的两个实例不是同一个实例");
//    }

//    LazySingleton lazySingleton1=LazySingleton.getInstance();
//    LazySingleton lazySingleton2=LazySingleton.getInstance();
//    if(lazySingleton1.hashCode()==lazySingleton2.hashCode()){
//      System.out.printf("获取到的两个实例是同一个实例");
//    }else{
//      System.out.printf("获取到的两个实例不是同一个实例");
//    }

    ThreadSafeSingleton lazySingleton1=ThreadSafeSingleton.getInstance();
    ThreadSafeSingleton lazySingleton2=ThreadSafeSingleton.getInstance();
    if(lazySingleton1.hashCode()==lazySingleton2.hashCode()){
      System.out.printf("获取到的两个实例是同一个实例");
    }else{
      System.out.printf("获取到的两个实例不是同一个实例");
    }
  }
}

运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aVdaSOHw-1574465125622)(evernotecid://AAA42DFC-EC45-4768-B516-25846DA75603/appyinxiangcom/12441645/ENResource/p1868)]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bigdatafreedom

你的鼓励奖是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值