Java笔记(三)Java中的单例模式
单例设计模式
何为单例模式?
简单来说,单例模式就是,一个类只允许一个实例化对象存在。
很多时候我们在整个程序或整个系统中,需要一个全局对象,此类中保存了一些在各个地方都能使用的一些配置信息,以此来看,单例设计模式就显得尤其重要了,我们不可能每次想看配置信息的时候都要创建实例化对象,那么太耗资源。
1、第一版单例设计模式
1 class Singleton { 2 //创建私有无参构造方法 3 private Singleton () {}; 4 //创建私有属性,初始设置为null; 5 private static Singleton singleton = null; 6 //创建获取对象的方法,静态工厂方法 7 public static Singleton getSingleton () { 8 //判断若是testb还是为null,那么创建对象,否则返回singleton对象 9 if (singleton == null) { 10 singleton = new Singleton(); 11 } 12 return singleton; 13 } 14 }
此段代码能实现单例模式,但是存在线程安全问题;
我们假设,在类刚刚被初始化,singleton对象还是空的,这时候有两个线程同时访问了getSingleton方法,那么就会创建出来两个对象,因为两个线程同时进行了if判断,而且两个线程是互不干扰的。
2、第二版单例设计模式
class Singleton { //创建静态无参构造方法 private Singleton (){} //定义私有的静态的属性 private static Singleton singleton = null; //创建静态公开的工厂方法 public static Singleton getTestC () { //判断属性是否为空 //1 if (singleton == null) { //加同步锁 //2 synchronized (Singleton.class) { //3 if (singleton == null) {//双重校验 //4 singleton = new Singleton(); } } } return singleton;//返回对象 } }
我们在1处,首先判断singleton是否为空,如果是第一次初始化实例对象肯定是空的,接着来到2,为了保证线程安全问题我们对类加了同步锁,此时就算来了两个线程,那也得老老实实的一个个排队走,接着在3处我们又进行了判断,假设有两个线程,那么第一个线程来到第3步要进行判断,为空,那么接着往下走,我们再回到第二个线程,也来到第3步就行判断,这时候就不是空了,直接return对象,因为第一个线程已经创建了对象,第二个判断肯定是为false的,那么就直接return singleton了。以此来实现了既保证线程安全又实现了单例设计模式。
在单例设计模式中有饿汉式和懒汉式的区分
饿汉式:
饿汉式的代码:
1 class Singleton { 2 //创建属性,直接创建实例化对象 3 private static Singleton singleton = new Singleton(); 4 //创建私有构造方法 5 private Singleton () {} 6 //创建静态工厂方法,获取对象的方法 7 public static Singleton getInstance() { 8 return singleton; 9 } 10 }
在此代码中,代码在进行类加载的时候,就直接为类的属性赋值,也就是在类加载的时候直接实例化对象,创建一个对象出来,这样当我们调用getInstance的时候,就能直接获取到对象,我们知道java中的类加载,只会在初始化类的时候才会进行一次,这样无论我们调用了多少次静态方法,都只是创建了一个对象出来,以此来实现了单例模式。
饿汉式的优点是,不存在线程安全的问题,因为在类加载的时候就直接实例化对象了。
缺点:可能会造成内存的浪费,因为在类加载的时候就完成了实例化,没有就行延迟加载,如果从始至终都没有用此对象,就浪费了内存资源。
懒汉式
上面写的就是懒汉式
优点:懒汉式是什么时候使用此对象的时候,才创建,如果从始至终都没有使用该对象,就不会创建,避免了资源的浪费
缺点:会有线程同步的问题,造成线程不安全。

浙公网安备 33010602011771号