开发工具与关键技术:MyEclipse
作者:邹铭霞
撰写时间:2019年5月6日
例如:当一个网站同时被访问时,单例模式相当一个管理员,管理员进行分配先给一个进入,两个不能同时进行
适用场景:
- 需要生成唯一序列的环境
- 需要频繁实例化然后销毁的对象。
- 创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
- 方便资源相互通信的环境
Java 单例模式有五种实现方式:
实现单例步骤:
1、隐藏构造器
2、定义一个变量放自身这个实例(实例自身这个类)
3、创建静态工厂方法,让外部可以获取实例(创建一个公共的static方法,这个方法返回自身实例)
一、饿汉式:
一开始就创建好实例,不管有没有用到
特点:线程安全,调用效率高,但是不能延时加载
public class Person1{
//实例化这个类
private static final Person1 INSTANCE = new Person1 ();
//隐藏构造器
private Person1 (){
}
//创建静态工厂方法,让外部可以获取实例
public static Person1 getInstance(){
return INSTANCE;
}
}
二、懒汉式:
延时加载,真正用的时候再创建实例
特点:线程安全,调用效率不高,但是能延时加载
public class Person2 {
//类初始化时,不初始化这个对象(延时加载,真正用的时候再创建)
private static Person2 instance;
// 私有化构造器
private Person2 () {
}
//方法同步,调用效率低
// 创建静态工厂方法 ,让外部可以获取实例
public static synchronized Person2 getInstance() {
if (instance == null) {
instance = new Person2 ();
}
return instance;
}
}
三、Double CheckLock实现单例:不建议使用
Double CheckLock也就是双重锁判断机制(由于JVM底层模型原因,偶尔会出问题,不建议使用)
public class Person3 {
private volatile static Person3 instance;
//私有化构造器
private Person3 () {
}
//静态工厂方法,双重锁判断机制
public static Person3 newInstance() {
if (instance == null) {
synchronized (Person3.class) {
if (instance == null) {第一个线程进来先把这段代码锁住,执行完了再放出来,才轮到下一个线程,保证代码只执行一次
instance = new Person3 ();
}
}
}
return instance;
}
}
四、静态内部类模式:
在class里面再定义class
特点:线程安全,调用效率高,可以延时加载
public class Person4 {
// 静态内部类
private static class SingletonClassInstance {
private static final Person4 instance = new Person4();
}
// 私有化构造器
private Person4() {
}
//静态工厂方法
public static Person4 getInstance() {
return SingletonClassInstance.instance;
}
}
五、枚举类:
特点:线程安全,调用效率高,不能延时加载,可以天然的防止反射和反序列化调用
public class Person5 {
//隐藏构造器
private Person5(){
}
//使用枚举
private static enum Singleton{
INSTANCE;
private Person5 singleton;
//JVM会保证此方法只调用一次
private Singleton(){
singleton = new Person5 ();
}
public Person5 getInstance(){
return singleton;
}
}
//创建静态工厂方法,让外部可以获取实例
public static Person5 getInstance(){
return Singleton.INSTANCE.getInstance();
}
}