单例模式:
1.什么是单例模式?
该模式的类只有一个实例。即一个类只有一个对象实例。
2.为什么使用单例?
减少内存消耗,提高效率,提高资源使用率
3.单例模式的特点(怎么判断这个类使用的是单例模式)
构造方法私有化
定义静态方法返回当前对象
final(不能被继承)
确保对象唯一
在序列化与反序列化操作过程中保证同一个对象
4.单例模式的几种表现方式:
- 恶汉式:
优点:不管你用不用,提前准备好,不会涉及线程问题
缺点:耗费内存
/**
* 单例模式-恶汉式
*/
public class Singleton {
private static Singleton singleton =new Singleton();
private Singleton() {
}
public static Singletonget instance() {
return singleton;
}
}
懒汉式:--单线程
优点:性能高 -> 在一定程度上节约了内存;用到了才创建
缺点:多线程问题很难解决
/**
* 单例模式-懒汉式
*/
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singletonget instance() {
if (instance ==null) {
instance =new Singleton();
}
return instance;
}
}
缺点问题:
加锁(synchronized)?
不加锁:多线程并发下创建多个对象
加锁:阻塞?如果10个线程访问这个对象,如果每个线程耗时3秒(等待上一个线程用完后,才允许使用)
/**
* 单例模式-线程安全
*/
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static synchronized Singletonget instance() {
if (instance ==null) {
instance =new Singleton();
}
return instance;
}
}
- 双重检查:折中方案
优点:既能够保证创建对象单例,同时保证了多线程安全
缺陷:为了提高代码稳定性,程序正确性,消耗性能
问题:双重检查失效
在java虚拟机(JVM 1.5之前)中Cache、寄存器到主内存回写数据顺序可能乱序(提高效率)
解决方案:
在java虚拟机1.5以及以后版本,加关键字volatile
volatile:去掉虚拟机优化代码
/**
* 单例模式-双重检查
*/
public class Singleton {
private static volatile Singleton instance;
private Singleton() {
}
public static Singletonget instance() {
if (instance ==null) {
//同步代码块
synchronized (Singleton.instance) {
if (instance ==null) {
instance =new Singleton();
}
}
}
return instance;
}
}
- 静态内部类:--多线程情况下,使用合理一点
既能够保证内存优化,同时保证线程安全
/**
* 单例模式-静态内部类
*/
public class Singleton {
private Singleton() {
}
public static Singletonget instance() {
return SingletonHolder.instance;
}
public static class SingletonHolder {
private static Singleton instance =new Singleton();
}
}
- 其它:枚举、集合方法-对象管理