设计模式之单例模式深究
时间:2022-04-29
本文章向大家介绍设计模式之单例模式深究,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
为什么使用单例模式? 我认为是由于某些对象的创建比较耗时,对内存的消耗又比较大回收成本过高,这时候如果允许 不断的创建对象代价势必太高,如果使用单例让内存中始终保持一个对象那么显然更划算
反例:
①. 同时执行1000个线程测试
public class Singleton3 {
private static Singleton3 INSTANCE;
private Singleton3(){}
public static Singleton3 getInstance(){
if(INSTANCE == null){
newInstance();
}
return INSTANCE;
}
private static void newInstance(){
INSTANCE = new Singleton3();
}
//test
public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
final CyclicBarrier cb = new CyclicBarrier(1000);
for(int i = 0; i <1000;i++){
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
cb.await();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Singleton3.getInstance().hashCode());
}
});
t.start();
}
}
测试结果通过notepad++计数发现有几个不一致的发现有不一致的hashcode
11009893 --不一致
31038155
31038155
31038155
31038155
31038155
31038155
31038155
31038155
31038155
31038155
31038155
31038155
26417394 --不一致
31038155
31038155
31038155
...
省略
②.加锁的方式:
public static Singleton3 getInstance(){
if (INSTANCE == null) {
try {
// 模拟一个耗时操作
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (Singleton3.class) {
newInstance();
}
}
return INSTANCE;
}
//结果显而易见
18000767
10320474
9913454
2027657
10262576
15487566
15487566
28392674
15487566
6268557
6268557
25920236
....略
③.双重检查加锁(即做两次判断):这种方式虽然可行,但是使用锁毕竟会加重程序不建议使用
if (INSTANCE == null) {
try {
// 模拟一个耗时操作
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (Singleton3.class) {
newInstance();
}
}
return INSTANCE;
}
private static void newInstance(){
if(INSTANCE == null){
INSTANCE = new Singleton3();
}
}
------------------------------------------
使用如下几种方式:
①.静态块的方式:只会第一次创建对象的方式进来
private static final Singleton2 INSTANCE;
static{
System.out.println("static.");
INSTANCE = new Singleton2();
}
private Singleton2(){}
public static Singleton2 getInstance(){
return INSTANCE;
}
②.类似于①
private static final Singleton INSTANCE = new Singleton();
private Singleton(){
System.out.println("construct.");
}
public static Singleton getInstance(){
return INSTANCE;
}
③.枚举的方式(必须是单元素):
public enum Singleton4 {
INSTANCE;
public int get(){
try {
// 模拟耗时
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Singleton4.class.hashCode();
}
}
④.静态内部类:略
------------------------------------
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 为WordPress添加自定义设置上传头像功能
- 229. 求众数 II Krains 2020-08-04 16:03:03 数学
- 部署 Consul服务实现Docker容器跨主机通信
- 【测试】 Java如何优雅的生成测试数据
- Spring事物的传播行为案例分析
- Ingress-nginx灰度发布功能详解
- [885]Tensorflow设置CUDA_VISIBLE_DEVICES来控制GPU的使用
- Windows10:启用或禁用休眠、保留的存储
- 基于Vue SEO的四种方案
- 一道SQL问题,你来试试的?
- 利用DNSLOG测试Fastjson远程命令执行漏洞
- goldengate classic模式在空闲数据库上抽取和应用数据延迟问题
- gorm jion查询映射(扫描scan)到新的结构体,必须使用select规定字段,与xorm的jion对比
- Spark UDF1 返回复杂结构
- Docker 部署Registry私有仓库+Harbor私有仓库