概念:**单例模式指的是不管你去创建多少次对象,对象始终都只有一个。**
这里主要介绍了四种方式
懒汉式:只在第一次调用的时候创建,之后不再创建。
public class SingletonLazy {private static SingletonLazy singletonLazy = null ;private String objName ;private SingletonLazy(){}public static SingletonLazy getSingletonLazy(){//此处线程不安全if (singletonLazy == null ){singletonLazy = new SingletonLazy();}return singletonLazy;}public String getObjName() {return objName;}public void setObjName(String objName) {this.objName = objName;}}
以上代码在标记线程不安全处会发生线程安全问题:
场景:线程1第一次来到标记处,此时singletonLazy 还是为null,所以马上要创建对象,但此时刚好分配的时间片用完,还未执行创建对象。此时线程2进入,应为此时singletonLazy还未创建,所以还是null,所以线程2能去创建对象。线程2创建完对象,然后这时线程1又开始执行了,此时会接着上次执行的代码处执行,即创建一个新的对象,此时就会创建出两个不一样的对象。
饿汉式
在类加载的时候就已经创建了,所以是线程安全的,但是就是消耗资源多。在不需要的时候也存在该对象。
public class SingletonHunger {private static SingletonHunger singletonHunger = new SingletonHunger();private SingletonHunger(){}public static SingletonHunger getSingletonHunger(){return singletonHunger;}}
静态内部类
其实就是在饿汉式的基础上的改进,因为饿汉式会在类加载的时候就创建对象,所以会消耗不必要的内存。所以我们引进内部类来创建对象,因为内部类的静态变量并不会随着外部类加载而创建。同时这个是一个线程安全的创建方式。
public class SingletStaticClass {SingletStaticClass(){}private static class InnerClass{//内部类加载的时候创建static final SingletStaticClass singletStaticClass = new SingletStaticClass();}public static SingletStaticClass getSingletStaticClass(){return SingletStaticClass.InnerClass.singletStaticClass;}}
双检查加锁
是懒汉式改进,因为懒汉式是一个线程不安全的单例模式,所以这里引进锁的方式。其实可以直接写一个同步方法的,但是这样性能太差了,不考虑。因此就在方法内加上锁,但是要又双重判断,不然也是会线程不安全的。
public class SingletDoubleLok {private static volatile SingletDoubleLok singleton;private SingletDoubleLok(){}public static SingletDoubleLok getSingletDoubleLok(){if (null == singleton){synchronized (singleton){if (null == singleton){singleton = new SingletDoubleLok();}}}return singleton;}}
