单例模式
核心:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点
常见场景
windows的任务管理器
windows的回收站
项目中,读取配置文件的类,一般也只有一个对象
网站的计数器一般也会采用单例模式,可以保证同步
数据库连接池的设计一般也是单例模式
在servlet编程中,每个servlet也是单例的
在spring中,每个bean默认就是单例的
优点:
由于单例模式只生成一个实例,减少了系统性能开销
单例模式可以在系统设置全局访问点,优化共享资源访问
常见的几种单例模式实现方式
饿汉式(线程安全,调用效率高,不能延时加载)
懒汉式(线程本身是不安全的,可以加锁使其安全,调用效率不高,可以延时加载)
饿汉式改进:静态内部类式(线程安全,调用效率高,可以延时加载)
枚举单例(线程安全,调用效率高,不能延时加载)
单例模式
//饿汉式单例
public class ehan {
//私有化构造器
private ehan(){
}
//类初始化的时候加载该对象
private static ehan a = new ehan();
//提供获取该对象的方法,没有synchronzied,效率高
public static ehan geta(){
return a;
}
}
//是否 Lazy 初始化:否
//是否多线程安全:是
//实现难度:易
//描述:这种方式比较常用,但容易产生垃圾对象。
//优点:没有加锁,执行效率会提高。
//缺点:类加载时就初始化,浪费内存。
//它基于 classloder 机制避免了多线程的同步问题,
//不过,instance 在类装载时就实例化,虽然导致类装载的原因有很多种,
//在单例模式中大多数都是调用 getInstance 方法,
//但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,
//这时候初始化 instance 显然没有达到 lazy loading 的效果。
//懒汉式
public class lanhan {
//私有化构造器
private lanhan(){
}
//类初始化的时候不立即加载该对象
private static lanhan a;
//提取获取该对象的方法,有synchronzied,效率低
public static synchronized lanhan geta(){
if (a==null){
a=new lanhan();
}
return a;
}
}
//是否 Lazy 初始化:是
//是否多线程安全:是
//实现难度:易
//描述:这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。
//优点:第一次调用才初始化,避免内存浪费。
//缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
//geta() 的性能对应用程序不是很关键(该方法使用不太频
//静态内部类
public class ehenshigaijin {
//私有化构造器
private ehenshigaijin(){
}
private static class innerclass{
private static ehenshigaijin a = new ehenshigaijin();
}
public static ehenshigaijin getInstance(){
return innerclass.a;
}
}
//枚举
public enum meiju {
Instance;
public meiju getInstance(){
return Instance;
}
}