2025年3月21日 星期五 甲辰(龙)年 月廿 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > 设计模式

【设计模式】9.创建型模式-单例模式(Singleton)

时间:02-01来源:作者:点击数:43

一、描述:

  某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,其拓展是有限多例模式。

二、特点:

  1.单例类只有一个实例对象

  2.该单例对象必须由单例类自行创建

  3.单例类对外提供一个访问该单例的全局访问点。

三、优点:

  1.单例模式可以保证内存里只有一个实例,减少了内存的开销。

  2.可以避免对自愿的多重占用。

  3.单例模式设置全局访问点,可以优化和共享资源的访问。

四、应用场景:

  1.需要频繁创建的一些类,使用单例可以降低系统的内存压力,减少GC。

  2.某些类创建实例时占用资源较多,或实例化耗时较长,且经常使用。

  3.某些类需要频繁实例化,而创建的对象又频繁被销毁的时候,如多线程的线程池,网络连接池等。

  4.频繁访问数据库或文件的对象。

  5.当对象需要被共享的场合。由于单例模式只允许创建一个对象,共享该对象可以节省内存,并加快对象访问速度。如Web中的配置对象、数据库的连接池等。

五、实现:

  1.饿汉模式(类初始化时就创建,线程安全)

  • public class HungaryTest {
  • private static final HungaryTest hungaryTest = new HungaryTest();
  • private HungaryTest() {
  • }
  • public static HungaryTest getHungaryTest() {
  • return hungaryTest;
  • }
  • }

  2.懒汉模式(需要的时候再创建,加volatile线程安全)

  • public class SafetyLazy2Test {
  • private static volatile SafetyLazy2Test safetyLazy2Test;
  • private SafetyLazy2Test() {
  • }
  • public static synchronized SafetyLazy2Test getLazyTest() {
  • if (safetyLazy2Test == null) {
  • System.out.println("safetyLazy2Test是空");
  • safetyLazy2Test = new SafetyLazy2Test();
  • }
  • System.out.println("safetyLazy2Test不是空");
  • return safetyLazy2Test;
  • }
  • }

  双重检测机制(DCL机制),同样可以实现线程安全

  • public class SafetyLazyTest {
  • private static volatile SafetyLazyTest safetyLazyTest;
  • private SafetyLazyTest() {
  • }
  • public static SafetyLazyTest getLazyTest() {
  • if (safetyLazyTest == null) {
  • synchronized (SafetyLazyTest.class) {
  • if (safetyLazyTest == null) {
  • System.out.println("lazyTest是空");
  • safetyLazyTest = new SafetyLazyTest();
  • }
  • }
  • }
  • System.out.println("lazyTest不是空");
  • return safetyLazyTest;
  • }
  • }

  线程测试:

  • @Slf4j
  • public class SafetyLazyThread extends Thread {
  • @Override
  • public void run() {
  • super.run();
  • log.info("safetyLazy:{}", SafetyLazyTest.getLazyTest().hashCode());
  • log.info("safetyLazy2:{}", SafetyLazy2Test.getLazyTest().hashCode());
  • }
  • }
  • public class ThreadTest {
  • public static void main(String[] args) {
  • safetyThreadTest();
  • }
  • private static void safetyThreadTest() {
  • SafetyLazyThread t1 = new SafetyLazyThread();
  • SafetyLazyThread t2 = new SafetyLazyThread();
  • SafetyLazyThread t3 = new SafetyLazyThread();
  • SafetyLazyThread t4 = new SafetyLazyThread();
  • t1.start();
  • t2.start();
  • t3.start();
  • t4.start();
  • }
  • }

  运行结果:

  • lazyTest是空
  • lazyTest不是空
  • lazyTest不是空
  • lazyTest不是空
  • lazyTest不是空
  • 10:55:32.381 [Thread-2] INFO com.my.project.designmode.singletoninstance.SafetyLazyThread - safetyLazy:1149747804
  • 10:55:32.381 [Thread-1] INFO com.my.project.designmode.singletoninstance.SafetyLazyThread - safetyLazy:1149747804
  • 10:55:32.381 [Thread-0] INFO com.my.project.designmode.singletoninstance.SafetyLazyThread - safetyLazy:1149747804
  • 10:55:32.381 [Thread-3] INFO com.my.project.designmode.singletoninstance.SafetyLazyThread - safetyLazy:1149747804
  • safetyLazy2Test是空
  • safetyLazy2Test不是空
  • safetyLazy2Test不是空
  • safetyLazy2Test不是空
  • 10:55:32.387 [Thread-2] INFO com.my.project.designmode.singletoninstance.SafetyLazyThread - safetyLazy2:1682859985
  • 10:55:32.387 [Thread-0] INFO com.my.project.designmode.singletoninstance.SafetyLazyThread - safetyLazy2:1682859985
  • 10:55:32.387 [Thread-1] INFO com.my.project.designmode.singletoninstance.SafetyLazyThread - safetyLazy2:1682859985
  • safetyLazy2Test不是空
  • 10:55:32.387 [Thread-3] INFO com.my.project.designmode.singletoninstance.SafetyLazyThread - safetyLazy2:1682859985

  3.静态内部类(线程安全,推荐使用。调用时才会创建。)

  • @Slf4j
  • public class StaticTest {
  • private static class StaticSingletonTest {
  • private static final StaticTest staticTest = new StaticTest();
  • }
  • private StaticTest() {
  • }
  • public static StaticTest getInstance() {
  • return StaticSingletonTest.staticTest;
  • }
  • }

  4.枚举模式

  • public enum EnumSingleton {
  • INSTANCE;
  • public EnumSingleton getInstance(){
  • return INSTANCE;
  • }
  • }
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门