小学生学习设计模式之单例模式
2020/4/7 17:02:02
本文主要是介绍小学生学习设计模式之单例模式,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
小学生学习设计模式之单例模式
一、什么是单例模式
单例模式(Singleton Pattern),涉及一个单一的类,该类负责创建自己的对象,确保只有单个对象创建,提供一种访问其唯一的对象的方式,可以直接访问,不需要实例该类的对象。
单例类只有一个实例,外部不能实例单例类,构造方法隐藏 单例类必须自己创建自己的唯一实例 单例类必须提供这一实例
二、实现
public class Singleton { /** * 唯一实例 */ private static Singleton instance = new Singleton(); /** * 构造方法隐藏,无法实例 */ private Singleton(){} /** * 提供外部访问唯一实例的方法 * @return */ public static Singleton getInstance(){ return instance; } public void message(){ System.out.println("This is Singleton Patterm"); } } 复制代码
public class SingletonPattermDemo { public static void main(String[] args) { Singleton instance = Singleton.getInstance(); Singleton singleton = Singleton.getInstance(); System.out.println(singleton == instance); instance.message(); } } /* * true * This is Singleton Patterm */ 复制代码
三、单例模式的几种实现方法
1. 懒汉式,线程不安全
public class Singleton { private static Singleton instance; private Singleton(){} public static Singleton getInstance(){ return instance = instance != null?instance:new Singleton(); } } 复制代码
2. 懒汉式,线程安全
public class Singleton { private static Singleton instance; private Singleton(){} public static synchronized Singleton getInstance(){ return instance = instance != null?instance:new Singleton(); } } 复制代码
3. 饿汉式
public class Singleton { private static Singleton instance = new Singleton(); private Singleton(){} public static Singleton getInstance(){ return instance; } } 复制代码
4. 双检锁/双重校验锁(DCL,double-checked locking)
public class Singleton { private volatile static Singleton instance; private Singleton(){} public static Singleton getInstance(){ if(instance == null){ synchronized (Singleton.class){ if(instance == null){ instance = new Singleton(); } } } return instance; } } 复制代码
5. 静态内部类
public class Singleton { private static class SingletonInstance{ private static final Singleton instance = new Singleton(); } private Singleton(){} public static final Singleton getInstance(){ return SingletonInstance.instance; } } 复制代码
6. 登记式
public class Singleton implements Serializable{ private static Map<String,Object> map; static{ map = new ConcurrentHashMap<>(); map.put(Singleton.class.getName(),new Singleton()); } private Singleton(){ System.out.println(Singleton.class.getName()); } public static final Object getInstance(String name){ if (name == null){ name = Singleton.class.getName(); } if(map.get(name) == null){ try { map.put(name,Class.forName(name).newInstance()); } catch (Exception e) { e.printStackTrace(); } } return map.get(name); } } 复制代码
7. 枚举(推荐)
public enum Singleton{ INSTANCE; } 复制代码
四、破解单例模式
1. 通过反射破解单例(枚举除外)
public class SingletonPattermDemo { public static void main(String[] args) throws Exception{ Class cla = Class.forName("cn.pzaily.Singleton"); Constructor constructor = cla.getDeclaredConstructor(null); constructor.setAccessible(true); Singleton singleton1 = (Singleton) constructor.newInstance(); Singleton singleton2 = (Singleton) constructor.newInstance(); System.out.println(singleton1 == singleton2); } } 复制代码
解决办法:
public class Singleton { private static final Singleton instance = new Singleton(); private Singleton(){ //在构造器中加个逻辑判断,多次调用抛出异常 if(instance != null){ throw new RuntimeException(); } } public static final Singleton getInstance(){ return instance; } } 复制代码
2. 通过反序列化机制破解单例(枚举除外)
public class SingletonPattermDemo { public static void main(String[] args) throws Exception { String path = "xxx"; Singleton instance1 = Singleton.getInstance(); Singleton instance2 = Singleton.getInstance(); Singleton instance3 = null; try(FileOutputStream fileOutputStream = new FileOutputStream(path); ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); FileInputStream fileInputStream = new FileInputStream(path); ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); ){ objectOutputStream.writeObject(instance1); instance3 = (Singleton) objectInputStream.readObject(); }catch (Exception e){ e.printStackTrace(); } System.out.println(instance1 == instance3); System.out.println(instance1 == instance2); } } 复制代码
解决办法
public class Singleton implements Serializable{ private static final Singleton instance = new Singleton(); private Singleton(){ if(instance != null){ throw new RuntimeException(); } } public static final Singleton getInstance(){ return instance; } //反序列化定义该方法,则不需要创建新对象 private Object readResolve() throws ObjectStreamException{ return instance; } } 复制代码
本文使用 mdnice 排版
这篇关于小学生学习设计模式之单例模式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-07-08如何在敏捷项目中实现高效测试?
- 2024-07-08用户故事一定要有 “So that...” 吗?
- 2024-07-04TiDB 资源管控的对撞测试以及最佳实践架构
- 2024-07-03万字长文聊聊Web3的组成架构
- 2024-07-02springboot项目无法注册到nacos-icode9专业技术文章分享
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt