ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-06-07 10:32:57  阅读:104  来源: 互联网

标签:Singleton SafetyLazyThread 模式 static private 单例 safetyLazy2Test 设计模式 public


一、描述:

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

二、特点:

  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;
    }
}

 

标签:Singleton,SafetyLazyThread,模式,static,private,单例,safetyLazy2Test,设计模式,public
来源: https://www.cnblogs.com/catxx/p/16261918.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有