单例模式
单例模式分两类,懒汉和饿汉,接下对懒汉和饿汉做介绍
懒汉式
在第一次调用的时候才实例化自己;懒汉式的优化和问题的症结都是围绕这个第一次调用;
饿汉模式
创建对象的时候就初始化。
-------------------------------------懒汉模式一---------------------
public class Singleton{
private Singleton(){}
private static Singleton single = null;
//静态工厂方法
public static Singleton getInstance(){
if(single == null){
single = new Singelton();
}
return single;
}
}
----------------双重检查锁定-----------------------------------------
public static Singleton getInstance(){
if(single == null){
synchronized(Singleton.class){
if(single == null){
single = new Singleton();
}
}
}
return single;
}
-------------------静态内部类------------------------
public class Singleton{
private static class LazyHolder{
private static final Singleton INSTANCE = new Singleton();
}
private Singleton(){}
public static final Singleton getInstance(){
return LazyHolder.INSTANCE;
}
}
---------------------------------------------------------------------
这个模式综合运用了java的类级内部类和多线程缺省同步锁的知识。
*什么是类级内部类?
简单点说,类级内部类指的是,有static修饰的成员式内部类。如果没有static修饰的成员式内部类叫对象级内部类。
*类级内部类相当于其外部类的static成分,他的对象与外部类对象间不存在依赖关系,因此可直接创建,而对象级内部类的实例,是绑定在外部对象实例中的。
*类级内部类中,可以定义静态的方法。在静态的方法中只能够引用外部类的中的静态成员方法或者成员变量。
*类级内部类相当于其外部类的成员,只有在第一次被使用的时候才会被装载。
再来看看多线程默认同步锁的知识。
在多线程开发中,为了解决并发问题,主要通过使用synchronized来加互斥锁进行同步控制。但是在某些情况中,JVM已经隐含的执行了同步,这些情况下就不用自己再来进行同步控制了,这些情况包括:
*由静态初始化器(在静态字段上或static{}块中的初始化器)初始化数据时
*访问 final 字段时
*再创建线程之前创建对象时
*线程可以看见他将要处理的对象时
由此想要很简单的实现线程安全,可以采用静态初始化器的方式,他可以由JVM来保证线程的安全性。比如饿汉式实现方式。但是这样一来,会浪费一定的空间,因为这种实现方式,会在类装载的时候就初始化对象,不管你需不需要。
如果现在有一种方法能够让类装载的时候不会初始化对象,不就解决问题了?一种可行的方式就是采用类级内部类,在这个累计内部类里面去创建对象实例。这样一来,只要不使用这个类级内部类,那就不会创建对象实例。从而同时实现延迟加载和线程安全。
--------------------------------饿汉模式-------------------------------------
public class Singleton{
private Singleton(){}
private static final Singleton single = new Singleton();
public static Single getInstance(){
reutrn single;
}
}
网友评论