Java|深入研究Java单例设计模式

欢迎点击「算法与编程之美」↑关注我们!

本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章。

简介

看到标题可能有人会问什么是单例模式呢?

在程序设计过程中,会遇到这么一个问题:当设计好一个类之后,会发现可以在别的类中调用类的构造方法实例化一个对象。并且通过实例化对象调用类中的属性和方法。

那么问题来了,如果存在某个类,这个类对于程序来说只需要产生一个类的时候,并且需要强制要求此类只能产生一个对象应该怎么办?这个时候就可以用到单例设计模式。所谓单例设计就是构造方法私有化,在类中实例化对象,通过类的静态方法调用类中的属性和方法。

其中单例设计又分为两种:

1.饿汉式:在系统加载类的时候就会自动提供实例对象。

2.懒汉式:在第一次使用的时候进行实例处理。

饿汉式

饿汉式单例设计模式就是在系统加载类的时候就会自动提供实例对象

那么如何才能实现饿汉式单例设计呢?可以将对象设置成一个静态的属性,再通过一个静态方法来获得这个属性。因为同一个类中静态属性只能静态访问。

下面来看看具体例子:

public  class Singleton {

    private static final Singleton SINGLETON  = new Singleton();

private Singleton() {

System.out.println("饿汉式单例设计构造方法");

 

    }

    public static Singleton getSingloten(){

        return SINGLETON;

    }

    public void print(){

        System.out.println("饿汉式单例设计");

    }

}

这就是一个单例设计的例子。在类中静态实例化了一个对象,并且有一个静态方法可以获得此对象。当需要用到此类时,直接通过类名就可以调用静态方法得到对象。

懒汉式

懒汉式单例设计是在第一次使用的时候进行实例处理。和饿汉式设计的区别就在于懒汉式设计是在调用静态方法的时候才会产生实例化对象,而不是系统直接提供。下面来看看具体事例:

通过这种单例设计我们就能达到只能得到一个对象的目的,但是这种懒汉式单例设计还是存在一个问题。是什么呢?来看看这个例子。

当使用多线程的时候调用静态方法获得对象的时候,运行结果说明并不是只产生一个对象,而是产生了三个对象。

运行结果如下图所示:

通过分析发现,在多线程中访问静态方法时,线程是同时访问的,并且同时判断对象是否为空。三个线程同时得到对象为空的结果,所以产生了三个对象。那么怎么去解决呢?可以通过线程的同步操作来实现这个操作。

实现方法如下:

同步操作就是当有一个线程在操作的时候,其他的线程就等待,这样就避免了线程同时获得对象为空的结果。但是这样加同步操作好像也不太合适,因为需要做的就只是同步操作判断对象是否为空的部分,所以将整个方法设为同步操作有点过于草率。因此还可以这样优化一下:

public  static Singleton getSingloten(){

        if (SINGLETON == null){

            synchronized (Singleton.class) {

                if (SINGLETON == null) {

                    SINGLETON = new  Singleton();

                }

            }

        }

        return SINGLETON;

    }

来看看运行结果:

构造方法确实是只被调用了一次,这样也达到了单例设计只产生一个对象的目的。有了这样的设计,单例设计才算是完美。

END

主  编   |   张祯悦

责  编   |   陶兴池

 where2go 团队


   

微信号:算法与编程之美          

长按识别二维码关注我们!

温馨提示:点击页面右下角“写留言”发表评论,期待您的参与!期待您的转发!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

算法与编程之美

欢迎关注『算法与编程之美』

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值