------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
单例设计模式:保证一个类在内存中只存在一个对象
1.避免其他程序过多建立该类对象,先禁止其他程序建立该类对象
2.为了让其他程序可以访问到该类对象,在本类中自定义一个对象
3.对外提供本类对象的访问方式
一、饿汉式
优点:代码简洁,线程安全。
缺点:类加载进内存时就自行创建了一个对象,该对象一直占用内存。
public class Single {
private Single(){//将构造函数私有化,就不能在本类以外调用该构造函数创建对象
}
private static final Single single = new Single();//在本类中创建一个对象
public static Single getSingle(){//调用此方法可以返回一个已经创建好的对象
return single;
// return new SingleTest();此处不能这么写,因为这样返回的是新建的对象,每次返回的对象都不同。
}
}
二、懒汉式
优点:延时加载,等要用该对象时才创建对象,不会像前种方式一直占用内存。
缺点:
简单的懒汉式线程不安全
public class Single {
private Single(){//将构造函数私有化,就不能在本类以外调用该构造函数创建对象
}
private static Single single = null;//先不创建对象
public static Single getSingle(){
if(single==null)//等函数被调用,外界需要用到Single类的对象时,再进行创建
single = new Single();
return single;
}
}
如果有多个线程同时进入if(single==null)这个判断条件内部,那么就会创建多个对象,违背了单例设计思想。
可以使用加同步锁来保证安全,但是程序执行效率会有影响
public class Single {
private Single(){//将构造函数私有化,就不能在本类以外调用该构造函数创建对象
}
private static Single single = null;//先不创建对象
public static synchronized Single getSingle(){//在函数外加锁,每次保证只有一个线程能够进入
if(single==null)//等函数被调用,外界需要用到Single类的对象时,再进行创建
single = new Single();
return single;
}
}
虽然在函数上加锁线程安全,但是每次调用该函数都会判断锁,对程序效率有影响,可以通过在方法内部加锁解决
public class Single {
private Single(){//将构造函数私有化,就不能在本类以外调用该构造函数创建对象
}
private static Single single = null;//先不创建对象
public static Single getSingle(){//在函数外加锁,每次保证只有一个线程能够进入
if(single==null)//等函数被调用,外界需要用到Single类的对象时,再进行创建
synchronized (Single.class) {//在条件内部加锁,防止多线程同时闯入
if(single==null)//加锁之后进行判断是必须的,加锁前的判断可以在对象创建后提高程序效率
single = new Single();
}
return single;
}
}
总结:
饿汉式虽然会一直占用内存,但是单例模式的对象迟早是要使用的,所以可以忽略那一小段时间,推荐使用饿汉式。
懒汉式虽然经过多次改进也很不错,但是代码太繁琐了。