单例 (JAVA)
java中单例模式是一种常见的设计模式,以下是它的特点:
- 单例类只能有一个实例。
- 单例类必须自己创建自己的唯一实例。
- 单例类必须给所有其他对象提供这一实例
第一种(懒汉,线程不安全):
2 private static Singleton instance;
3
4 public static Singleton getInstance() {
5 if (instance == null) {
6 instance = new Singleton();
7 }
8 return instance;
9 }
10 }
11
懒汉式是典型的时间换空间,就是每次获取实例都会进行判断,看是否需要创建实例,浪费判断的时间。当然,如果一直没有人使用的话,那就不会创建实例,则节约内存空间
由于懒汉式的实现是线程安全的,这样会降低整个访问的速度,而且每次都要判断.
第二种(懒汉,线程安全):
2 private static Singleton instance;
3
4 public static synchronized Singleton getInstance() {
5 if (instance == null) {
6 instance = new Singleton();
7 }
8 return instance;
9 }
10 }
11
第三种(饿汉):
2 private static Singleton instance = new Singleton();
3
4 public static Singleton getInstance() {
5 return instance;
6 }
7 }
8
第四种(饿汉,变种):
2 private Singleton instance = null;
3 static {
4 instance = new Singleton();
5 }
6
7 public static Singleton getInstance() {
8 return this.instance;
9 }
10 }
11
表面上看起来差别挺大,其实更第三种方式差不多,都是在类初始化即实例化instance。
第五种(静态内部类):
2 private static class SingletonHolder {
3 private static final Singleton INSTANCE = new Singleton();
4 }
5
6 public static final Singleton getInstance() {
7 return SingletonHolder.INSTANCE;
8 }
9 }
10
优点:加载时不会初始化静态变量INSTANCE,因为没有主动使用,达到Lazy loading
第六种(枚举):
2 INSTANCE;
3 public void whateverMethod() {
4 }
5 }
6
优点:不仅能避免多线程同步问题,而且还能防止反序列化
第七种(双重校验锁):
2 private volatile static Singleton singleton;
3
4 public static Singleton getSingleton() {
5 if (singleton == null) {
6 synchronized (Singleton.class) {
7 if (singleton == null) {
8 singleton = new Singleton();
9 }
10 }
11 }
12 return singleton;
13 }
14 }
15
总结
有两个问题需要注意:
1、如果单例由不同的类装载器装入,那便有可能存在多个单例类的实例。假定不是远端存取,例如一些
servlet容器对每个
servlet使用完全不同的类 装载器,这样的话如果有两个
servlet访问一个单例类,它们就都会有各自的实例。
2、如果
Singleton实现了
java.io.Serializable接口,那么这个类的实例就可能被序列化和复原。不管怎样,如果你序列化一个单例类的对象,接下来复原多个那个对象,那你就会有多个单例类的实例。
对第一个问题修复的办法是:
2 throws ClassNotFoundException {
3 ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
4
5 if(classLoader == null)
6 classLoader = Singleton.class.getClassLoader();
7
8 return (classLoader.loadClass(classname));
9 }
10 }
11
对第二个问题修复的办法是:
2 public static Singleton INSTANCE = new Singleton();
3
4 protected Singleton() {
5
6 }
7 private Object readResolve() {
8 return INSTANCE;
9 }
10 }
11
单例 (JAVA)的更多相关文章
- 单例 ------ JAVA实现
单例:只能实例化一个对象,使用场景比如打印机. 最推荐的是采用饿汉式:双重校验锁用到了大量的语法,不能保证这些语法在所用场合一定没问题,所以不是很推荐:总之简单的才是最好的,就饿汉式!!! C++ 创 ...
- javaWeb项目中到底什么是单例,多例
你用杯子喝可乐,喝完了不刷,继续去倒果汁喝,就是单例.你用杯子喝可乐,直接扔了杯子,换个杯子去倒果汁喝,就是多例. 数据库连接池就是单例模式,有且仅有一个连接池管理者,管理多个连接池对象. 1. 什么 ...
- java 单例
Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍两种:懒汉式单例.饿汉式单例. 饿汉式和懒汉式区别 从名字上来说,饿汉和懒汉, 饿汉就是类一旦加载,就把单例初始化完成,保证 ...
- Java设计模式之单例
一.Java中的单例: 特点: ① 单例类只有一个实例 ② 单例类必须自己创建自己唯一实例 ③ 单例类必须给所有其他对象提供这一实例 二.两种模式: ①懒汉式单例<线程不安全> 在类加载时 ...
- java单例的几种实现方法
java单例的几种实现方法: 方式1: public class Something { private Something() {} private static class LazyHolder ...
- Java 多线程之单例设计模式
转载:https://segmentfault.com/a/1190000007504892 概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍两种:懒汉式单例.饿汉 ...
- java单例类/
java单例类 一个类只能创建一个实例,那么这个类就是一个单例类 可以重写toString方法 输出想要输出的内容 可以重写equcal来比较想要比较的内容是否相等 对于final修饰的成员变量 一 ...
- java单例-积木系列
一步步知识点归纳吧,把以前似懂非懂,了解表面,知道点不知道面的知识归一下档. 懒汉式单例: 私有化构造函数,阻止外界实例话对象,调用getInstance静态方法,判断是否已经实例化. 为什么是懒 ...
- 如何防止JAVA反射对单例类的攻击?
在我的上篇随笔中,我们知道了创建单例类有以下几种方式: (1).饿汉式; (2).懒汉式(.加同步锁的懒汉式.加双重校验锁的懒汉式.防止指令重排优化的懒汉式); (3).登记式单例模式; (4).静态 ...
随机推荐
- 六款小巧的HTTP Server[C语言]
1.micro_httpd - really small HTTP server特点: 支持安全的 .. 上级目录过滤 支持通用的MIME类型 支持简单的目录 支持目录列表 支持使用 index.ht ...
- 比较两个文件文件可以使用MD5比较工具
举例来说,当我们对一个设备进行升级. 固件程序是一个文件,而我们发送的数据可以组成一个文档, 实质是把这两个文件拖入到下图中的工具中,查看一下MD5值.SHA1值.CRC32的值,如果值都一样说明这两 ...
- hdu 4281(MTSP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4281 题意:给出N个点,第一个点是裁判,其他N-1个点需要裁判过去回答问题,每个点需要的时间不一样,而 ...
- ios 时间和毫秒数转换
01-时间和毫秒数的相互转换 //获取毫秒数的时间戳 long inter = [[NSDate date] timeIntervalSince1970]*1000; NSLog(@"%ld ...
- T-SQL优化
我们做软件开发的,大部分人都离不开跟数据库打交道,特别是erp开发的,跟数据库打交道更是频繁,存储过程动不动就是上千行,如果数据量大,人员流动大,那么我么还能保证下一段时间系统还能流畅的运行吗?我么还 ...
- LoadRunner 脚本学习 -- 读取文件内容
随便创建个txt文档 输入点内容,例如 读取文件内前N个字符: Action() { long myfile; ; ]; char *filename = "E:\\kkk.txt&quo ...
- hdu 5306 优先队列
用到优先队列 #include<iostream> #include<string> #include<algorithm> #include<cstdio& ...
- Tomcat不输入项目名进入自己项目(根目录指向自己的项目)
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDepl ...
- Webbrowser中显示MHT文件
把MHT文件存成临时文件,用WEBBROWSER的Navigate方法打开,代码如下: //从程序集中读取资源文件 Assembly asmm = Assembly.GetCallingAssembl ...
- poj 1321 棋盘问题
八皇后问题变形,回溯法. #include <cstdio> #include <cstring> #include <iostream> using namesp ...