东西不用就会忘,昨天去面试就问到了单例模式,虽然答出了,但感觉不是回答的很好,这里在复习一下
单例模式
保证一个类只有一个实例,并且提供一个访问实例的全局访问点,目的是使防止一个类全局使用,频繁的创建销毁,节省资源,如数据库连接池,spring中的bean等。
让类自身负责保存它的唯一实例,这个类没有其他实例可创建,并且他可以提供一个访问该实例的方法,关键就是构造方法私有。
单例模式几种实现方式
1,饿汉模式
/**
* @Author : FuYu
* @Despriotion : 饿汉模式
* 一开始就进行实例化,线程安全
* 缺点:类加载就初始化,浪费内存
*/
public class ESingleton {
/**
* static为的是能在getSingleton()方法中调用
*/
private static ESingleton singleton = new ESingleton();
private ESingleton()
{
}
public static ESingleton getSingleton()
{
return singleton;
}
}
2,懒汉模式 线程不安全
/**
* @Author : FuYu
* @Despriotion :懒汉模式 不安全
* 线程不安全,不能在多线程的环境下使用
*/
public class LSingleton {
private static LSingleton singleton;
private LSingleton()
{
}
/**
* synchronized 和static位置可以互换
* @return
*/
public static synchronized LSingleton getInstance(){
if(singleton == null)
{
singleton = new LSingleton();
}
return singleton;
}
}
3,懒汉模式 线程安全
/**
* @Author : FuYu
* @Despriotion : 懒汉 线程安全
* 调用的时候才初始化,节约资源,相比非线程安全对全局访问点加synchronized
*/
public class LASingleton {
private static LASingleton singleton;
private LASingleton()
{
}
public static synchronized LASingleton getSingleton()
{
if(singleton == null)
{
singleton = new LASingleton();
}
return singleton;
}
}
4,双重锁检验
**
* @Author : FuYu
* @Despriotion : 双重校验锁
* 适合多线程情况,安全且在多线程情况下能保持高性能
*/
public class LockSingleton {
private static LockSingleton singleton;
private LockSingleton()
{
}
public static LockSingleton getSingleton()
{
//第一次判断是否为null
if(singleton == null)
{
//加锁
synchronized (LockSingleton.class)
{
//防止多线程已经进行过实例化再次校验
if (singleton == null)
{
singleton = new LockSingleton();
}
}
}
return singleton;
}
}
5,静态内部类
/**
* @Author : FuYu
* @Despriotion : 静态内部类
* 线程安全,延迟实例化,也能达到和双重检验锁一样的效果
* 外部类加载时并不需要立即加载内部类,内部类不被加载则不去初始化INSTANCE,故而不占内存。
*/
public class StaticSingleton {
private static class SingletonHolder
{
private static StaticSingleton INSTANCE = new StaticSingleton();
}
private StaticSingleton()
{
}
public static final StaticSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
6,枚举
/**
* @Author : FuYu
* @Despriotion : 枚举
* effective java里介绍用单元素的枚举是实现单例的最佳方法
* 菜鸟:它不仅能避免多线程同步问题,而且还自动支持序列化机制,
* 防止反序列化重新创建新的对象,绝对防止多次实例化。
* 不过,由于 JDK1.5 之后才加入 enum 特性,用这种方式写不免让人感觉生疏,在实际工作中,也很少用。
*/
public enum EnumSingleton {
INSTANCE;
public void whateverMethod() {
}
}
待完善:实例操作,从jvm的方向来看类加载