美文网首页
单例模式(Singleton)

单例模式(Singleton)

作者: tingshuo123 | 来源:发表于2018-08-17 10:40 被阅读5次

简介:

单例模式时Java中最简单也最常用的的设计模式之一,它属于建造模式的一种,我们称使用了单例模式的类称为单例类,单例类需要负责创建自己的对象,同时确保只会生成一个实例,要注意不要被 GC 回收,也就是说,JVM 只存在该对象的一个实例。

单例模式的优点:

  • 只会有一个实例存在,避免了反复创建销毁实例,降低内存使用率,减轻 GC 的压力。
  • 避免对资源的多重占用

单例模式有两种:

  • 懒汉式,懒汉式会延时加载对象,也就是说在需要的时候才创建实例。
  • 饿汉式,饿汉式是即时加载的,在类加载时就会创建实例。

写单例模式要点:

  1. 创建一个静态变量,用来引用自身。
  2. 私用化构造方法,避免被外界调用,产生多个对象。
  3. 提供一个工厂方法,共外界获取该类实例。
  4. 要注意不要重复创建实例。

懒汉式

package singleton;
/**
 * 懒汉式单例模式,延时加载,调用时才实例化自己
 * 单例:一个 Jvm 中,该对象只有一个实例
 * 缺点:多线程下不安全
 * @author wqj24
 *
 */
public class LazySingleton {
    
    private static LazySingleton instance = null;
    
    // 限制产生多个对象
    private LazySingleton() {
        
    }
    
    // 静态工厂方法
    public static LazySingleton getInstance() {
        // 避免重复创建
        if (instance == null) {
            instance = new LazySingleton();
        }
        
        return instance;
    }
}

考虑多线程的的懒汉式

将创建对象的方法独立出来,并使用synchronized 关键字加锁

public class Singleton {
    private static SingletonTest instance = null;

    private SingletonTest() {
    }

    private static synchronized void syncInit() {
        if (instance == null) {
            instance = new SingletonTest();
        }
    }

    public static SingletonTest getInstance() {
        if (instance == null) {
            syncInit();
        }
        return instance;
    }
}

注意上面两个if都有各自的作用,并没有冗余。

饿汉式

package singleton;

public class EagerSingleton {
    
    // 私有化类变量,防止被引用,类被第一次加载时实例化(只实例化一次)
    private static EagerSingleton instance = new EagerSingleton();
    
    // 私有化构造方法
    private EagerSingleton() {
        
    }
    
    // 静态工厂方法
    public static EagerSingleton getInstance() {
        
        return instance;
    }
}

测试:

package singleton;

import org.junit.Test;

public class TestMain {
    
    // 懒汉单例模式测试
    @Test
    public void lazyTest() {
        LazySingleton s1 = LazySingleton.getInstance();
        LazySingleton s2 = LazySingleton.getInstance();
        System.out.println(s1 == s2);
    }
    
    // 恶汉单例模式测试
    @Test
    public void eagerTest() {
        EagerSingleton s1 = EagerSingleton.getInstance();
        EagerSingleton s2 = EagerSingleton.getInstance();
        System.out.println(s1 == s2);
    }
    
}

结果都是 true。

相关文章

网友评论

      本文标题:单例模式(Singleton)

      本文链接:https://www.haomeiwen.com/subject/qghzbftx.html