单例模式
单例模式是一种常用的软件设计模式。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
1.单例模式特点
- a.单例类只能有一个实例。
- b.单例类必须自己创建自己的唯一实例。
- c.单例类必须给所有其他对象提供这一实例。
2.单例模式作用
- 保证java应用程序中,一个类Class中只能有一个实例。
3.单例模式种类
- a.饿汉式
- b.懒汉式
- c.懒汉式 - 同步方法
- d.懒汉式 - 双重检测
- e.懒汉式 - 内部类
单例模式 - 饿汉式
/**
* 饿汉式单例模式
* 优点:线程安全
* 缺点:在加载类的时候就实例化对象,浪费资源,没有延迟加载
* @author long
*
*/
public class Singleton1 {
//饿汉式直接初始化
private static Singleton1 instance = new Singleton1();
private Singleton1(){
}
public static Singleton1 getInstance(){
return instance;
}
}
懒汉式单例模式
/**
* 懒汉式单例模式
* 优点:类初始化不直接加载
* 缺点:多线程不安全,当两个线程同时检查到singleton为空,则都进行实例化
* @author long
*
*/
public class Singleton2 {
private static Singleton2 singleton;
private Singleton2(){
}
public static Singleton2 getInstance(){
if(singleton == null){
singleton = new Singleton2();
}
return singleton;
}
}
懒汉式-方法同步
/**
* 懒汉式-方法同步
* 优点:线程安全
* 缺点:对方法进行了同步,每次调用getInstance方法都对锁进行了判断,比较耗时
* @author long
*
*/
public class Singleton3 {
private static Singleton3 singleton;
private Singleton3(){
}
public static synchronized Singleton3 getInstance(){
if(singleton == null){
singleton = new Singleton3();
}
return singleton;
}
}
懒汉式 - 双重检查
/**
* 懒汉式 - 双重检查
* 优点:双重检测有效地避免了资源浪费的情况,只有在第一次调用getInstance()方法时才会初始化,不用每次都判断锁状态
* 缺点:多线程中仍然不安全
* 例如:多线程的涉入可能会导致instance还没有初始化完成就被当做完整的实例返回给了应用程序了。也就是说线程1正在实例化instance,
线程2运行到1这个位置发现instance不为空,那么按程序的流程就应该返回instance,但是这个时候的instance还未被实例化完成。
* @author long
*
*/
public class Singleton4 {
private static Singleton4 instance;
private Singleton4(){
}
public static Singleton4 getInstance(){
//判断存在的必要性在于提高性能,只有第一次调用getInstance()方法是才会被调用。
if(instance == null){
synchronized(Singleton4.class){
//判断存在的必要性在于实现单例,当很多线程在同步块外面等待一个个进入时,如果发现instance不为空了,则不实例化。
if(instance == null){
instance = new Singleton4();
}
}
}
return instance;
}
}
懒汉式 - 内部类
/**
* 懒汉式 - 内部类
* 优点:实现了延时加载,没有在类被加载的时候就去实例化对象。
* @author long
*
*/
public class Singleton5 {
private Singleton5(){
}
private static Singleton5 getInstance(){
return SingletonHolder.instance;
}
private static class SingletonHolder{
public static Singleton5 instance = new Singleton5();
}
}