首页 > 其他分享 >设计模式:单例模式

设计模式:单例模式

时间:2023-01-17 19:02:41浏览次数:39  
标签:Singleton 模式 public LazyMan static private 单例 设计模式 class


最近谷咕咕在学习设计模式,都说不会设计模式的程序员是读不懂框架源码的,而且写出的代码是架构底下的。行吧,那只好卷一下,看看各个设计模式的优点。
这里先是看了狂神的视频,然后对照菜鸟教程浏览了一下,其中不懂的知识点就去百度,当然百度了也不懂的,大可不必太深究。总结:还是要自己敲代码,运行,看结果去理解。光看要是不懂的话不用太烦,反正是挺晦涩的。
首先看最简单的设计模式:

单例模式

提供创建的对象的最佳方式。
注意:
1.单例类只能有一个实例。
2.单例类必须自己创建自己的唯一实例。
3.单例类必须给所以其他对象提供这一实例。

关键:构造器私有,私有保证只能自己创建自己的实例。
实现单例的多种方式
1.懒汉式
通俗来讲,就是比较懒,不用的时候就没有这个实例,用到了才创建对象实例。
懒汉式,下面的3的代码就是在懒汉式上写的。

public class Singleton {  
private static Singleton instance;
private Singleton (){}

public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}

要是想线程安全就锁上类

public class Singleton {  
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}

2.饿汉式
饿汉式其实就是在类装载的时候就实例化,容器造成垃圾对象。

package single;

/**
* @author ymgu
* @version V1.0
* @Package single
* @date 2022/3/21 10:59
*/
public class Hungry {
private Hungry(){

}
private final static Hungry HUNGRY=new Hungry();
public static Hungry getInstance(){
return HUNGRY;
}
}

3.双重校验锁
所谓的双重校验锁其实就是使用synchronized 锁住类,然后volatile防止指令重排

package single;

import java.lang.reflect.Constructor;

/**
* @author ymgu
* @version V1.0
* @Package single
* @date 2022/3/21 9:58
*/
public class LazyMan {
//单例模式一定要构造器私有
private LazyMan(){
synchronized (LazyMan.class){
if(lazyMan!=null){
throw new RuntimeException("不要通过反射破坏单例");
}
}
}
//防止指令重排volatile
private volatile static LazyMan lazyMan;

public static LazyMan getInstance(){
if (lazyMan==null){
//锁住该类,防止出现多线程创建多个对象
synchronized (LazyMan.class){
if (lazyMan==null){
lazyMan=new LazyMan();
}
}
}
return lazyMan;
}

public static void main(String[] args) throws Exception {
LazyMan lazyMan=LazyMan.getInstance();
Constructor<LazyMan> declaredConstructor=LazyMan.class.getDeclaredConstructor(null);
//破坏其的私有权限
declaredConstructor.setAccessible(true);
LazyMan lazyMan2=declaredConstructor.newInstance();
System.out.println(lazyMan);
System.out.println(lazyMan2);

}

}

4.静态内部类
今天内部类的实现方式和双重校验锁效果一样,但是可以延迟初始化,这一块吧,我就没有深究。

package single;

import com.sun.org.apache.bcel.internal.classfile.InnerClass;

/**
* @author ymgu
* @version V1.0
* @Package single
* @date 2022/3/21 10:08
*/
public class Holder {
private Holder(){
}
public static Holder getInstance(){
return InnerClass.HOLDER;
}
public static class InnerClass{
private static final Holder HOLDER=new Holder();
}

}

5.枚举

如果通过反射来破坏,就会报异常,enum是实现了方式反射的

设计模式:单例模式_单例模式

package single;

import java.lang.reflect.Constructor;

/**
* @author ymgu
* @version V1.0
* @Package single
* @date 2022/3/21 10:34
*/
//反射不能破坏枚举的单例
public enum EnumSingle {
INSTANCE;
public EnumSingle getInstance(){
return INSTANCE;
}
}
class Test{
public static void main(String[] args) throws Exception {
EnumSingle enumSingle1=EnumSingle.INSTANCE;
EnumSingle enumSingle2=EnumSingle.INSTANCE;
System.out.println(enumSingle1);
System.out.println(enumSingle2);
Constructor<EnumSingle> declaredConstructor=EnumSingle.class.getDeclaredConstructor(String.class,int.class);
declaredConstructor.setAccessible(true);
EnumSingle enumSingle3=declaredConstructor.newInstance();
System.out.println(enumSingle3);

}
}

最后引用菜鸟的话
经验之谈:一般情况下,不建议使用第 1 种和第 2 种懒汉方式,建议使用第 3 种饿汉方式。只有在要明确实现 lazy loading 效果时,才会使用第 5 种登记方式。如果涉及到反序列化创建对象时,可以尝试使用第 6 种枚举方式。如果有其他特殊的需求,可以考虑使用第 4 种双检锁方式。


标签:Singleton,模式,public,LazyMan,static,private,单例,设计模式,class
From: https://blog.51cto.com/u_15601494/6017723

相关文章

  • 必须退出播放模式才能保存场景
    必须退出播放模式才能保存场景 unity报错,怎么办?可以 不可以 ......
  • Springboot整合策略模式概念->使用场景->优缺点->企业级实战
    一、前言策略模式可能是在工作中使用最多的,也是在面试中最常提到的,代码重构和优化的必备!小编之前也是一直说,其实没有真正的实战;最近有了机会实战了一下,来分享一下使用心得......
  • openwrt单口旁路由模式开启ipv6
    光猫改桥接硬路由拨号并开启ipv6这些不用说了百度一大堆确保你硬路由拨号那边配置好ipv6并在电脑上测试得到了ipv6地址可以通过test-ipv6.com监测我这边是esir编译......
  • 建造者模式
    建造者模式定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示作用:在用户不知道对象的建造过程和细节的情况下,可以直接创建复杂的对......
  • 原型模式
    原型模式原型模式(PrototypePattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。1、使用方法实现Cl......
  • 代理模式
    代理模式即ProxyPattern,23种java常用设计模式之一。代理模式的定义:对其他对象提供一种代理以控制对这个对象的访问。代理模式也是SpringAOP的底层代理模式分类:静态......
  • 工厂模式+抽象工厂模式
    工厂模式1、概述核心实例化对象不使用new,用工厂方法代替将选择实现类,创建对象统一管理和控制。从而将调用者跟我们的实现类解耦工厂模式满足的OOP原则:开闭原则......
  • 单例模式
    单例模式1、概述核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点常见场景:Window的任务管理器Window的回收站项目中,读取配置文件的类,一般......
  • 22.(行为型模式)java设计模式之备忘录模式
    一、什么是备忘录模式(MementoPattern)定义:在不破坏封闭的前提下,捕获⼀个对象的内部状态,保存对象的某个状态,以便在适当的时候恢复对象,⼜叫做快照模式,属于⾏为模式。备......
  • 04-代理模式
    04代理模式背景本博客是照着程杰的《大话设计模式》一书实现的Java代码的版本,再加自己的一点理解问题卓贾易追求娇娇的方式是派出自己的好友戴笠实现该模型的代码逻辑......