传送门:单例模式的优缺点和使用场景–http://www.cnblogs.com/damsoft/p/6105122.html
单例模式的好处:–http://blog.youkuaiyun.com/ljhljh8888/article/details/8017701/
为什么要用单例?
一个类Class只有一个实例存在,限制实例的个数,节省内存,有利于Java垃圾回收(garbage collection)。【一般manager类行的类多使用单例】
怎样创建单例:将构造函数私有化,通过静态方法获取唯一实例。
public class Singleton {
/* 持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */
private static Singleton instance = null;
/* 私有构造方法,防止被实例化 */
private Singleton() {
}
/* 静态工程方法,创建实例 */
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
/* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */
public Object readResolve() {
return instance;
}
}
注意点:当唯一实例尚未创建时,有两个线程同时调用创建方法,那么它们同时没有检测到唯一实例的存在,从而同时各自创建了一个实例, 这样就有两个实例被构造出来,从而违反了单例模式中实例唯一的原则。 解决这个问题的办法是为指示类是否已经实例化的变量提供一个互斥锁(但是这样会降低效率)。
因此在多线程的情况下,最好使用饿汉式单例模式,即:
private static class SingletonFactory{
private static Singleton instance = new Singlet();
public static Singleton getInstance(){
return SingletonFactory.instance;
}
}
但是要注意的是:static修饰的方法和变量都无法被继承.
提一下,什么是懒汉式单例和饿汉式单例。
懒汉式单例:
见名知意,比较懒,在类加载的时候不创建实例,什么时候调用创建类的方法,什么时候创建实例。(多线程中容易出现问题)
public class LazySingleton {
//懒汉式单例模式
//比较懒,在类加载时,不创建实例,因此类加载速度快,但运行时获取对象的速度慢
private static LazySingleton intance = null;//静态私用成员,没有初始化
private LazySingleton()
{
//私有构造函数
}
public static synchronized LazySingleton getInstance() //静态,同步,公开访问点
{
if(intance == null)
{
intance = new LazySingleton();
}
return intance;
}
}
饿汉式单例:比较饿,所以从类加载的时候就立即创建实例。
public class EagerSingleton {
//饿汉单例模式
//在类加载时就完成了初始化,所以类加载较慢,但获取对象的速度快
private static EagerSingleton instance = new EagerSingleton();//静态私有成员,已初始化
private EagerSingleton()
{
//私有构造函数
}
public static EagerSingleton getInstance() //静态,不用同步(类加载时已初始化,不会有多线程的问题)
{
return instance;
}
}
有什么问题,请留言。