单利模式的核心结构中包含一个被称为单利的特殊类,通过单例模式可以保证系统中,应用该模式的 类只有一个实例对象。
1.单利模式的优缺点;
优点:系统中该类的对象的实例只有一个,节省了系统资源,对于一些需要频繁创建和销毁的对象,使用单利模式可以提高系统性能。
缺点:要想实例化单例时,必须要记住获取对象的方法,而不是使用new方法,可能会给开发者带来困扰
2.适用场所:
需要频繁的创建和销毁对象
创建对象时耗时过多或消耗资源过多,又经常使用到的对象。
工具栏对象
频繁访问数据库或者文件的对象。
3.单利模式分为两种懒汉模式和恶汉模式
懒汉模式:在类初始化的时候不进行初始化
恶汉模式:在类加载完的时候就完成了初始化,所有类一块加载,加载速度较慢,但是获取对象速度较快。
1.恶汉模式(静态常量)
public class SingleMode{
private final static SingleMode INSTANCE = new SingleMode();
private SingleMode(){}
public static SingleMode getInstance(){
return INSTANCE;
}
}
优点:写法比较简单,在类加载的时候就完成了创建,避免了线程同步的问题
缺点:在类加载的时候就完成了创建,没有达到懒加载的目的,如果至始至终没有使用过这个实例,会造成资源浪费。
2恶汉模式(静态代码块)
public class SingleMode{
private static SingleMode sInstance;
static {
sInstance = new SingleMode()
}
public static SingleMode getInstance(){
return sInstance;
}
}
几乎和方法1一样,只不过是将实例化的过程放在了静态代码块中,也是在类加载的时候就执行了静态代码块中的数据,优缺点和方法1一样。
3.懒汉模式(线程不安全)
public class SingleMode(){
private static SingleMode instance;
private SingleMode(){}
public static SingleMode getInstance(){
if(instace == null){
instance = new SingleMode;
}
return instance;
}
}
一般只在单线程中使用,如果在多线程中使用可能会产生多个实例,因此不采用。
4.懒汉模式(线程安全)
public class SingleMode{
private SingleMode instance;
private SingleMode(){}
public static synchronized SingleMode getInstance(){
if(instance == null){
instance = new Singlemode();
}
return instance;
}
}
解决了线程不安全的问题,但是每个线程想要获得类的实例时,都需要调用getInstance()方法进行同步,效率太低。
5.懒汉模式(线程安全,同步代码块,不在同步整个方法)
public class SingleMode{
private SingleMode sInstance;
private SingleMode(){}
public static SingleMode getInstance(){
if(sInstance == null){
synchronized(this){
sInstance = new SingleMode();
}
}
return sInstance;
}
}
这种方式看是方法四的优化,其实不然,这种方式和第三种一样,并不能保证线程安全,例如一个线程进入了if(sInstance == null)判断语句,还未来得及创建实例,此时另外一个线程也通过了这个判断语句,此时就会产生多个实例。
6.懒汉模式双重检查(线程安全)
public class SingleMode{
private static SingleMode sInstance;
private SingleMode(){}
public static SingleMode getInstance(){
if(sInstance == null){
synchronized(this){
if(sInstance == null){
sInstance = new SingleMode();
}
}
}
return sInstance;
}
}
双重检查在多线程中很常见,在代码中,进行了两次if(sInstance == null)的检查,这样就可以保证了线程安全
优点:线程安全,延迟加载,效率较高
7.静态内部类
public class SingleMode{
private SingleMode(){}
private static class SingleHolder{
private static final SingleMode INSTANCE = new SingleMode();
}
public static SingleMode getInstance(){
reruen SingleHolder.INSTANCE;
}
}
静态内部类的实现方式和恶汉模式采用的机制类似,但是又有所不同,两者都采用了类加载的机制来保证初始化时,只有一个线程。不同的地方在于恶汉模式只要SingleMode类被加载就会初始化,没有懒加载的作用,而静态内部类在SingleMode类被加载时不会立即实例化。而是在需要实例化的时候才会调用getInstance,从而加载SingleHolder类,完成SingleMode的实例化。
优点,避免了线程不安全,延迟加载,效率高
8.枚举
public enum SingleMode{
INSTANCE;
public void whateverMethod(){
}
}
JDK1.5以后才出现的单例模式,不仅能避免多线程问题而且还能防止反序列化重新创建新的对象。项目中很少用到。
网友评论