经典案例:单例模式之懒汉式和饿汉式

    科技2022-07-12  145

    单例模式之懒汉式和饿汉式


    文章目录

    单例模式之懒汉式和饿汉式一、单例模式是什么?二、几种单例模式1.懒汉模式2.饿汉模式 三、懒汉模式和饿汉模式的区别


    一、单例模式是什么?

    保证整个系统中一个类只有一个对象的实例,实现这种功能的方式就叫单例模式。 单例模式实现格式一般为:

    构造方法私有化定义一个该类的静态变量对外提供一个public返回实例的静态方法

    二、几种单例模式

    1.懒汉模式

    在初始化类的时候,不创建唯一的实例,而是等到真正需要用到的时候才创建。可以理解为一个懒人,饿的时候才想起要创建一个(吃饭)对象。 注意必须加上同步,否则有可能依然创建多个实例。

    代码如下:

    //多线程下的单例模式 懒汉模式 public class A1 { //定义一个该类的静态变量 public static A1 a; //构造方法私有化 private A1(){ } //对外提供一个public返回实例的静态方法 public synchronized static A1 getInstance(){ if (a==null){ //如果该变量为null,生成该对象 a = new A1(); return a; }else { //如果不为不null,直接返回该对象 return a; } } } //测试类 public class TestA1 extends Thread{ @Override public void run() { //调用A1的getInstance()方法的hashCode值,即对象的哈希值,来判断是否为单例 System.out.println(Thread.currentThread().getName()+"--->"+A1.getInstance().hashCode()); } public static void main(String[] args) { TestA1 threadA1 = new TestA1(); threadA1.setName("苹果"); threadA1.start(); TestA1 threadA2 = new TestA1(); threadA2.setName("香蕉"); threadA2.start(); TestA1 threadA3 = new TestA1(); threadA3.setName("橘子"); threadA3.start(); } }

    运行结果如下,通过哈希值可以判断是一个单例对象。

    2.饿汉模式

    在初始化的时候,就创建了唯一的实例,不管是否需要用到。就像一个饿了好久的人,一上来就先创建一个(吃饭)对象。不需要自己加同步,一定产生唯一的实例。

    代码如下:

    //单例模式之饿汉模式 public class E { //定义一个该类的静态变量 private static E e = new E(); //构造方法私有化 private E(){ } //对外提供一个public返回实例的静态方法 public static E getInstance(){ return e; } } //测试类 public class TestE extends Thread{ @Override public void run() { //调用E的getInstance()方法的hashCode值,即对象的哈希值,来判断是否为单例 System.out.println(Thread.currentThread().getName()+"--->"+E.getInstance().hashCode()); } public static void main(String[] args) { TestE testE1 = new TestE(); testE1.setName("苹果"); testE1.start(); TestE testE2 = new TestE(); testE2.setName("香蕉"); testE2.start(); TestE testE3 = new TestE(); testE3.setName("橘子"); testE3.start(); } }

    运行结果如下,通过哈希值可以判断是一个单例对象。

    三、懒汉模式和饿汉模式的区别

    饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变。懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的。

    从实现方式来讲他们最大的区别就是懒汉式是延时加载,懒汉式是在需要的时候才创建对象,而饿汉式在虚拟机启动的时候就会创建,饿汉式无需关注多线程问题,写法简单明了,能用则用。但是它是加载类时创建实例。所以如果是一个工厂模式,缓存了很多实例,那么就得考虑效率问题,因为这个类一加载则把所有实例不管用不用一块创建。

    两者建立单例对象的时间不同。“懒汉式”是在你真正用到的时候才去建这个单例对象,“饿汉式”是在不管用不用得上,一开始就建立这个单例对象。

    Processed: 0.012, SQL: 8