今天我们来探讨一下设计模式的创建型模式的第一个:单例模式
单例模式应用面特别的广泛,因为它的设计模式就是整个项目环境中只能存在一个静态对象实例,这就会使资源的复用性增强,避免了在项目中有些高频使用的对象频繁的创建和销毁,降低了系统的性能!
单例模式分为饿汉式的单例模式和懒汉式的单例模式!这两种都有各的好处,没有什么绝对的谁就一定更胜一筹的说法。
饿汉式单例模式
public class HungryMan {
private static HungryMan hungryMan=new HungryMan();
public static HungryMan getInstance(){
return hungryMan;
}
}
以上是创建了一个饿汉的类,里面就定义了一个静态的对象实例,并创建了一个静态方法让外界能够拿到此对象又不会暴露一些细节。这个线程是绝对安全的,因为这个是静态实例对象随着类的加载而加载,而JVM底层的初始化加载是线程安全的。
public static void main(String[] args) {
HungryMan instance1 = HungryMan.getInstance();
HungryMan instance2 = HungryMan.getInstance();
System.out.println(instance1 == instance2); //此答案为true
}
此时我们写一个主线程运行一下,成功通过饿汉类的静态方法拿到这个对象,为了证实从头到尾我们始终用的是同一个对象,我在取了两次对比,发现两者对象的地址值是相同的,由此可以说明就是同一个对象!像这种写法在各种框架底层或jdk底层都大量使用的,只要深入源码解析自然可以看到。(后期我也会写一些源码剖析的文章和大家一起讨论)
懒汉式单例模式
public class LazyMan {
private volatile static LazyMan lazyMan;
public static LazyMan getInstance(){
if (lazyMan==null){
synchronized (LazyMan.class){
if (lazyMan==null){
return lazyMan=new LazyMan();
}
}
}
return lazyMan;
}
}
上面就是懒汉式的一种常规写法,懒汉式与饿汉式不同的是,一个一开始就创建好另一个有需求了再创建。所以初始化时是一个空对象,这里用到了synchronize同步锁机制 是因为这个对象并不是类初始化时创建的,而是在有需求调用时才创建的,有可能会引发多线程调用同一个方法,破坏对象的单例设计模式,所以必须上锁!当第一个线程进入创建了对象后,后面的线程便不会再进行同步操作,而是直接返回对象了,不会因为同步而降低效率,这也凸显出设计模式的强大之处!
public static void main(String[] args) {
LazyMan instance3 = LazyMan.getInstance();
LazyMan instance4 = LazyMan.getInstance();
System.out.println(instance3 == instance4); //true
}
最后同样多次调用方法取出对象,判断引用地址是否相同,结果也是显而易见的为true,就是懒汉式的单例模式。
最后总结:饿汉、懒汉各有好处,饿汉式在类加载变初始化成功,产生对象随时都可调用。懒汉式的按需加载,既可以节约内存空间,需要时又可以即时调用。具体要用哪种模式,要看业务需求适合哪种模式。真实世界上没有一个事物或人是完美无瑕的,只有适合自己的才是最好的。正如这篇文章一样如果你觉得还行,其中的内容也适合自己或身边朋友,可以评论或转发,这是给笔者莫大的鼓励哦!