java设计模式——单例模式(三)
容器单例模式
之前学习Structs2,Spring框架时,经常会听到单例,多例。虽然这与单例模式不太一样,但是都很类似。在程序运行的时候,就加载所有的实例,然后用的时候直接取出
看下面代码:
/**
* @program: designModel
* @description: 容器单例模式
* @author: YuKai Fan
* @create: 2018-12-11 14:59
**/
public class ContaineSingleton {
private ContaineSingleton() {}
private static Map<String, Object> singletonMap = new HashMap<String, Object>(); public static void putInstance(String key, Object instance) {
if (StringUtils.isNotBlank(key) && instance != null) {
if (!singletonMap.containsKey(key)) {
singletonMap.put(key, instance);
}
}
} public static Object getInstance(String key) {
return singletonMap.get(key);
}
}
但是,这种方式在不考虑序列化与反射的情况下,依旧是不安全的。因为在多线程的环境下,还是会产生不同的实例,这需要结合场景来使用。
如果使用hashTable来保证线程安全的话,效率会很低,频繁去取实例都回家加同步锁。如果使用ConcurrentHashMap,由于被static修饰,相当于直接操作了 map,在这种场景下,也不是绝对的线程安全。
ThreadLocal环境下的"单例模式"
这种带引号的单例模式,并不是真正的单例模式。因为并不能保证整个应用只产生一个实例,只会保证整个应用线程唯一
/**
* @program: designModel
* @description:
* @author: YuKai Fan
* @create: 2018-12-11 15:17
**/
public class ThreadLocalInstance {
private static final ThreadLocal<ThreadLocalInstance> threadLocalInstance = new ThreadLocal<ThreadLocalInstance>(){
@Override
protected ThreadLocalInstance initialValue() {
return new ThreadLocalInstance();
}
};
private ThreadLocalInstance() {} public static ThreadLocalInstance getInstance() {
return threadLocalInstance.get();
} }
/**
* @program: designModel
* @description:
* @author: YuKai Fan
* @create: 2018-12-04 14:11
**/
public class T implements Runnable {
public void run() { ThreadLocalInstance instance = ThreadLocalInstance.getInstance();
System.out.println(Thread.currentThread().getName() + "" + instance); }
}
/**
* @program: designModel
* @description:
* @author: YuKai Fan
* @create: 2018-12-04 14:07
**/
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// LazySingleton lazySingleton = LazySingleton.getInstance();
Thread t1 = new Thread(new T());
Thread t2 = new Thread(new T());
t1.start();
t2.start();
System.out.println("测试");
}
}
输出结果:

产生的是不同的实例,但是ThreadLocal回味每个线程提供独立的变量副本,将每个线程的实例隔离。保证在多线程的情况下,会保证每个线程只能产生一个实例
单例模式源码分析
单例模式在jdk下的应用:
java.lang.Runtime下的getRuntime()方法,属于饿汉式
AWT下的Desktop类中的getDesktop()——容器单例的影子
Spring中的单例与之前介绍的单例不一样,
spring中的单例是在bean作用域中的一个,这个作用域在每个应用程序上下文中仅创建一个我们设置单例属性的这个实例;与之前介绍的单例模式最大的区别在于Spring讲实例的数量限制在每个应用程序的上下文,而之前的单例模式中的实例,是将数量限制在给定的类加载器管理的整个空间里。所以Spring容器中,即使设置属性为单例,都可以拿出来这个对象。
在AbstractFactoryBean中的getObject()方法,可以看到单例模式的影子。
MyBatis中的单例模式:
ErrorContext类,保证每个线程的各自数据,使用的就是单例模式,也就是ThreadLocal的单例模式。
java设计模式——单例模式(三)的更多相关文章
- Java设计模式(三) 抽象工厂模式
原创文章,同步发自作者个人博客,转载请注明出处 http://www.jasongj.com/design_pattern/abstract_factory/ 抽象工厂模式解决的问题 上文<工厂 ...
- Java设计模式の单例模式
-------------------------------------------------- 目录 1.定义 2.常见的集中单例实现 a.饿汉式,线程安全 但效率比较低 b.单例模式的实现:饱 ...
- JAVA设计模式-单例模式(Singleton)线程安全与效率
一,前言 单例模式详细大家都已经非常熟悉了,在文章单例模式的八种写法比较中,对单例模式的概念以及使用场景都做了很不错的说明.请在阅读本文之前,阅读一下这篇文章,因为本文就是按照这篇文章中的八种单例模式 ...
- Java设计模式 - - 单例模式 装饰者模式
Java设计模式 单例模式 装饰者模式 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 静态代理模式:https://www.cnblogs.com/StanleyBlogs/p/1 ...
- java设计模式单例模式 ----懒汉式与饿汉式的区别
常用的五种单例模式实现方式 ——主要: 1.饿汉式(线程安全,调用率高,但是,不能延迟加载.) 2.懒汉式(线程安全,调用效率不高,可以延时加载.) ——其他: 1.双重检测锁式(由于JVM底层内部模 ...
- 【设计模式】Java设计模式 - 单例模式
[设计模式]Java设计模式 - 单例模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 分享学习心得,欢迎指正,大家一起学习成长! 原创作品,更多关注我CSDN: ...
- Java 设计模式 —— 单例模式
1. 概念: 单例模式是一种常用的软件设计模式.核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源.如果 ...
- Java设计模式 - 单例模式 (懒汉方式和饿汉方式)
概念: Java中单例模式是一种常见的设计模式,单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 单例模式的写法有好几种,这 ...
- java设计模式——单例模式(一)
一. 定义与类型 定义:保证一个类仅有一个实例,并提供一个全局访问点 类型:创建型 二. 适用场景 想确保任何情况下都绝对只用一个实例 三. 优缺点 优点: 在内存里只有一个实例,减少了内存开销 可以 ...
随机推荐
- Zookeeper下载方法
Zookeeper官网地址:http://zookeeper.apache.org/ Zookeeper下载链接:http://mirrors.tuna.tsinghua.ed ...
- tp5模型事件回调函数中不能使用$this
tp5模型事件回调函数中不能使用$this,使用会报错,涉及到数据库操作使用Db类,不能使用$this->save()之类的方式 如果回调函数中需要使用类内函数,需要将函数定义为static,通 ...
- 设计模式——单例模式(Singleton)
保证一个类仅有一个实例,并提供一个访问它的全局访问点.——DP UML类图 模式说明 个人认为单例模式是所有设计模式中最为简单的一个模式,因为实现这个模式仅需一个类,而不像其他模式需要若干个类.这个模 ...
- Python+Selenium----使用HTMLTestRunner.py生成自动化测试报告2(使用PyCharm )
1.说明 在我前一篇文件(Python+Selenium----使用HTMLTestRunner.py生成自动化测试报告1(使用IDLE ))中简单的写明了,如何生产测试报告,但是使用IDLE很麻烦, ...
- Oracle 11g安装报错Environment variable: "PATH"
Environment variable: "PATH" - This test checks whether the length of the environment vari ...
- new 和 delete 用法
1. 这两个其实是 C++ 语言标准库的库函数,原型分别如下: void *operator new(size_t); //allocate an object void *operator dele ...
- hibernate log4j2输出sql带参数
网上有很多是输出sql ,参数以?的形式,后面输出参数binding的log,还要自己拼接特别麻烦:这里整理下输出原生sql的方法.组件是log4jdbc 1: 修改pom.xml,确定有下面的配置, ...
- ace admin 左侧菜单定位
后台模版来自:Ace Admin http://ace.jeka.by/form-elements.html 左侧菜单,通过js根据url来判断显示哪块 window.location.pathnam ...
- WPF动画的几种模式
最近在用WPF做简单动画,以下是几点经验总结: 1. 使用DispatcherTimer做动画 VB6的年代大家就用Timer做动画了,不用多解释,这个DispatcherTimer和本身的Timer ...
- 学习笔记:MDN的服务器端网站编程
互联网是如何工作的 互联网(Internet)和网络(web) 互联网是基础设施,网络是建立在这种基础设施之上的服务. 网页,网站,网络服务器和搜索引擎的区别是什么? 网页(webpage) 一份能够 ...