JAVA设计模式之【单例模式】

server/2024/10/19 6:21:26/

<a class=单例模式.png" />

1 类图

2 饿汉式单例

例如:静态块、静态成员

2.1 概念

类加载的时候就立即初始化,并且创建单例对象

2.2 优点

没有加任何的锁、执行效率比较高

2.3 缺点

类加载的时候就初始化,不管用与不用都占着空间,浪费了内存。

3 懒汉式单例

3.1 直接:线程不安全

java">public class LazySimpleSingleton {private LazySimpleSingleton(){}//静态块,公共内存区域private static LazySimpleSingleton lazy = null;public  static LazySimpleSingleton getInstance(){if(lazy == null){lazy = new LazySimpleSingleton();}return lazy;}
}

3.2 同步方法

java">public class LazySimpleSingleton {private LazySimpleSingleton(){}//静态块,公共内存区域private static LazySimpleSingleton lazy = null;public synchronized static LazySimpleSingleton getInstance(){if(lazy == null){lazy = new LazySimpleSingleton();}return lazy;}
}

3.2.1 优化CPU:双重检查锁

java">public class LazyDoubleCheckSingleton {private volatile static LazyDoubleCheckSingleton lazy = null;private LazyDoubleCheckSingleton(){}public static LazyDoubleCheckSingleton getInstance(){if(lazy == null){synchronized (LazyDoubleCheckSingleton.class){if(lazy == null){lazy = new LazyDoubleCheckSingleton();//1.分配内存给这个对象//2.初始化对象//3.设置lazy指向刚分配的内存地址//4.初次访问对象}}}return lazy;}
}

3.2.2 IDEA 环境下的多线程调试

3.3 静态内部类

这种形式兼顾饿汉式的内存浪费,也兼顾synchronized性能问题,完美地屏蔽了这两个缺点

java">//史上最牛B的单例模式的实现方式
public class LazyInnerClassSingleton {//默认使用LazyInnerClassGeneral的时候,会先初始化内部类//如果没使用的话,内部类是不加载的private LazyInnerClassSingleton(){if(LazyHolder.LAZY != null){throw new RuntimeException("不允许创建多个实例");}}//每一个关键字都不是多余的//static 是为了使单例的空间共享//保证这个方法不会被重写,重载public static final LazyInnerClassSingleton getInstance(){//在返回结果以前,一定会先加载内部类return LazyHolder.LAZY;}//默认不加载private static class LazyHolder{private static final LazyInnerClassSingleton LAZY = new LazyInnerClassSingleton();}
}

3.3.1 反射破坏单例

在构造函数上抛出异常

java">    private LazyInnerClassSingleton(){if(LazyHolder.LAZY != null){throw new RuntimeException("不允许创建多个实例");}}

3.3.2 序列化破坏单例

增加 readResolve()方法

java">public class SeriableSingleton implements Serializable {public  final static SeriableSingleton INSTANCE = new SeriableSingleton();private SeriableSingleton(){}public static SeriableSingleton getInstance(){return INSTANCE;}private  Object readResolve(){return  INSTANCE;}
}

4 注册式单例

4.1 枚举式单例

利用jdk特性。具有线程安全、实例唯一(杜绝反序列化破坏单例)的特点。
java">public enum EnumSingleton {INSTANCE;private Object data;public Object getData() {return data;}public void setData(Object data) {this.data = data;}public static EnumSingleton getInstance(){return INSTANCE;}
}

4.1.1 优点

线程安全、实例唯一

4.2 容器缓存写法

java">public class ContainerSingleton {private ContainerSingleton(){}private static Map<String,Object> ioc = new ConcurrentHashMap<String,Object>();public static Object getInstance(String className){synchronized (ioc) {if (!ioc.containsKey(className)) {Object obj = null;try {obj = Class.forName(className).newInstance();ioc.put(className, obj);} catch (Exception e) {e.printStackTrace();}return obj;} else {return ioc.get(className);}}}
}

4.2.1 优点

对象方便管理、懒加载

4.2.2 缺点

不加上synchronized存在线程安全问题

5 ThreadLocal-线程单例

5.1 写法

java">public class ThreadLocalSingleton {private static final ThreadLocal<ThreadLocalSingleton> threadLocalInstance =new ThreadLocal<ThreadLocalSingleton>(){@Overrideprotected ThreadLocalSingleton initialValue() {return new ThreadLocalSingleton();}};private ThreadLocalSingleton(){}public static ThreadLocalSingleton getInstance(){return threadLocalInstance.get();}
}

5.2 优点

保证在单个线程中是唯一


http://www.ppmy.cn/server/106973.html

相关文章

【三种循环结构】for循环、while循环和do-while循环

在C/C语言中&#xff0c;循环结构是编程中常用的控制结构之一&#xff0c;用于重复执行一段代码直到满足特定条件。C/C语言主要提供了三种循环结构&#xff1a;for循环、while循环和do-while循环。 1.for循环&#xff1a; for循环是最常用的循环结构之一&#xff0c;它的一般形…

项目中Redis常见的一些问题(缓存穿透,缓存雪崩,内存耗尽等)

缓存穿透 缓存穿透是指查询一个不存在的数据&#xff0c;导致每次请求查询这个不存在的数据 都会转发到数据库&#xff0c;可能导致数据库崩溃 通常都会用布隆过滤器来解决它 布隆过滤器 布隆过滤器主要是用于检索一个元素是否在一个集合中。 它的底层主要是先去初始化一个…

Rust: Reading and Writing Files

Reading and Writing Files We need some way to actually get data from the filesystem so we can process it, and write it back when we’re done 我们需要某种方法从文件系统中实际获取数据&#xff0c;以便处理它&#xff0c;并在完成后将其写回来 use std::fs;std::f…

80、k8s概念及组件介绍

一、k8s kubernetes:k8s----希腊语&#xff0c;舵手&#xff0c;飞行员 1.1、k8s作用&#xff1a; ​ 用于自动部署&#xff0c;扩展&#xff0c;管理容器化部署的应用程序。开源&#xff08;半开源。&#xff09; ​ k8s的底层语言是由go语言。 ​ k8s理解成负责自动化运…

PostgreSQL 内核资源管理

在高负载环境下&#xff0c;尤其是在同一系统上运行多个 PostgreSQL 实例或在大型安装环境中&#xff0c;PostgreSQL 有时可能会耗尽操作系统的资源限制。本文介绍了 PostgreSQL 使用的关键内核资源&#xff0c;以及如何解决与这些资源消耗相关的问题。 19.4.1. 共享内存和信号…

小程序常用的模板语法

WXML 文件 <!-- page.wxml --> <view><!-- 数据绑定: 将数据 message 绑定到视图中 --><view>{{message}}</view><!-- 条件渲染: 根据 isLoggedIn 的值显示不同的内容 --><view wx:if"{{isLoggedIn}}">Welcome back!<…

内网横向移动常用方法

横向移动 #横向移动含义 横向移动是以已经被攻陷的系统为跳板&#xff0c;通过收集跳板机的信息&#xff08;文档&#xff0c;存储的凭证&#xff0c;ipc连接记录等等信息&#xff09;来访问其他域内主机。#常见横向手段 1&#xff0c;通过相同的用户名密码批量ipc连接其他域内…

Godot《躲避小兵》实战之为游戏添加音效

现在&#xff0c;我们已经完成了游戏的所有功能。以下是一些剩余的步骤&#xff0c;为游戏加点“料”&#xff0c;改善游戏体验。 随意用你自己的想法扩展游戏玩法。 背景 默认的灰色背景不是很吸引人&#xff0c;那么我们就来改一下颜色。一种方法是使用 ColorRect节点。将…