首页 > 其他分享 >【设计模式】——你真的会单例吗?

【设计模式】——你真的会单例吗?

时间:2022-12-05 17:37:46浏览次数:59  
标签:设计模式 getInstance INSTANCE static Mar1 单例 真的 public


【简介】

单例模式,属于创建类型的一种常用的​​软件设计​​模式。通过单例模式的方法创建的类在当前进程中只有一个实例(根据需要,也有可能一个线程中属于单例,如:仅线程上下文内使用同一个实例)

【设计模式】——你真的会单例吗?_java

【场景】

现实中有意思的场景可以查阅小编之前总结的一篇博客:​​找对象需要单例模式吗?​​

适用单例的条件:

一、某个类只能有一个实例

二、是它必须自行创建这个实例

三、是它必须自行向整个系统提供这个实例。

单例具体实现要求:

一、是单例模式的类只提供私有的构造函数

二、是类定义中含有一个该类的静态私有对象

三、是该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象。

【示例】

一、饿汉式,私有静态变量初始化方式(简单易用,能满足大部分要求)

说明:类加载到内存后,就实例化一个单例,jvm保证线程安全(缺点:不管用到与否,类装载时就会完成实例化)

public class Mar1 {
private static Mar1 INSTANCE = new Mar1();
private Mar1(){}

public static Mar1 getInstance(){
return INSTANCE;
}

public static void main(String[] args) {
Mar1 mar1 = Mar1.getInstance();
Mar1 mar11 = Mar1.getInstance();
System.out.println(mar1 == mar11);
}

}

二、懒汉式,锁方法

说明:需要用到的时候再进行实例创建(缺点:并发带来效率低下的问题)

注:volatile关键字可以规避指令重排带来的不安全性(idea中可以查看编辑指令)

public class Mar4 {
private static volatile Mar4 INSTANCE;
private Mar4(){}

public static synchronized Mar4 getInstance(){
if(INSTANCE == null){
//测试并发加入的睡眠
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
INSTANCE = new Mar4();
}
return INSTANCE;
}

public static void main(String[] args) {
for (int i = 0; i<100;i++){
new Thread(()->{
System.out.println(Mar4.getInstance().hashCode());
}).start();
}
}

}

三、懒汉式,局部锁,双重判定

说明:需要用到的时候再进行实例创建,相对于二的效率得到了一些提升

public class Mar6 {
private static volatile Mar6 INSTANCE;
private Mar6(){}

public static Mar6 getInstance(){
if(INSTANCE == null){
synchronized(Mar6.class){
if(INSTANCE == null) {
//测试并发加入的睡眠
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
INSTANCE = new Mar6();
}
}
}
return INSTANCE;
}

public static void main(String[] args) {
for (int i = 0; i<100;i++){
new Thread(()->{
System.out.println(Mar6.getInstance().hashCode());
}).start();
}
}

}

四、懒汉式,内部类实现

说明:类加载的时候不会去加载内部类,当使用到调用的时候才会进行实例化

public class Mar7 {
private Mar7(){}
private static class Mar7Holder{
private static Mar7 INSTANCE = new Mar7();
}

public static Mar7 getInstance(){
return Mar7Holder.INSTANCE;
}

public static void main(String[] args) {
for (int i = 0; i<100;i++){
new Thread(()->{
System.out.println(Mar7.getInstance().hashCode());
}).start();
}
}

}

五、枚举方式(effectice java书中提到的)

说明:不仅可以解决线程安全还可以防止反序列化

public  enum  Mar8 {

INSTANCE;

public static void main(String[] args) {
for (int i = 0; i<100;i++){
new Thread(()->{
System.out.println(Mar8.INSTANCE.hashCode());
}).start();
}
}

}

【总结】

通过学习各种形式的单例模式,对单例又有了一个更加深刻的认识。

1.利用java中的特性来解决(内部类、枚举类)

2.使用锁的时候要在保证安全的前提控制锁的粒度

3.通过学习单例对以后code更有干劲

4.激发了自己了解其它模式更加浓厚的兴趣与爱好

标签:设计模式,getInstance,INSTANCE,static,Mar1,单例,真的,public
From: https://blog.51cto.com/u_14471711/5913091

相关文章

  • 读王明毅、冯兴元翻译的《通往奴役之路》,不得不感慨这翻译水平真的是烂
    读王明毅、冯兴元翻译的《通往奴役之路》,咋就和百度翻译上直接copy下来的一样呢,这译者的中文水平真是不敢恭维,这水平估计高考时候作文成绩高不了。 不是我说些什么,这现在的......
  • 单例设计模式
    单例设计模式什么是单例设计模式所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个实例对象,并且该类只提供一个取得其对象实例的方......
  • 软件设计模式之模拟游角色选择(Darren建造者模式)
    o(︶︿︶)o唉,今天的状态不是很好,但是学习还是要继续的,今天和大家一起分享一下建造者模式,记得之前自己之前一直再想QQ秀换装是怎么是怎么是实现的,今天看了建造者模式我明白了........
  • 软件设计模式之外观设计模式(Darren)
    先回顾一下之前我们已经讲过的设计模式:简单工厂模式,策略模式,单一职责原则,开放封闭原则,依赖倒转原则,装饰模式,抽象工厂模式,模板方法模式,迪米特法则;今天我们来讲一下......
  • Selenium4+Python3系列(十) - Page Object设计模式
    前言​​PageObject(PO)​​​模式,是​​Selenium​​实战中最为流行,并且被自动化测试同学所熟悉和推崇的一种设计模式之一。在设计测试时,把页面元素定位和元素操作方法按照......
  • 设计模式之代理模式学习分享[Darren]
    很高兴又在每晚的这个时候和博友有分享今天的学习成果了,感谢大家一直对Darren的支持,也希望各位博友们能将自己的好文章分享出来,在此Darren只是抛砖,希望大家不要吝啬自己的学......
  • Spring中配合hibernate使用的简单例子
    最近在看SPRING和hibernate,学习了spring和hibernate之间整合,下面举出一个例子予以说明.    首先,可以注入的是sessionfactory,因为sessionfactory的Datasource可以......
  • 单例模式常用模板类
    单例模式可以确保软件生命周期内仅有一个实例化对象,方便各处便利调用。单例模板类申明定义如下:template<typenameT>classSingleTon{public:staticT&getIns......
  • 设计模式——初学学习经验
    设计模式各位读者朋友你们好,我是你们的好朋友IT黑铁,在这学期的学习过程中初步认识和学习了设计模式和架构思想。以下内容最全的几个是我当前有点理解的模式,其余内容缺少的......
  • 前端修炼之路-设计模式
    什么是设计模式?在软件开发程中通用的解决方案。目前有23中设计模式设计原则:单一职责原则(SRP)、开放封闭原则(OCP)、最少知识原则(LKP)1、代理模式场景1:花店替人送花//声明......