单例模式与synchronized

Posted LVXIANGAN

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例模式与synchronized相关的知识,希望对你有一定的参考价值。

单例模式中的懒汉模式,通常看到代码如下:

public class Person 
    private static Person mInstance;

    public static Person getInstance(Context context) 
        if (null == mInstance) 
            mInstance = new Person();
        
        return mInstance;
    

上述代码其实属于线程不安全的懒汉模式,原因在于无法对多线程调用进行控制:
1、线程A希望使用Person,调用getInstance()方法。因为是第一次调用,A就发现instance是null的,于是它开始创建实例,就在这个时候,CPU发生时间片切换,

2、线程B开始执行,它也要使用Person,调用getInstance()方法,同样检测到instance是null——注意,这是在A检测完之后切换的,也就是说A并没有来得及创建对象——因此B开始创建。B创建完成后,切换到A继续执行,因为它已经检测完了,所以A不会再检测一遍,它会直接创建对象。这样,线程A和B各自拥有一个Person对象,最终导致单例失败!

要实现线程安全的单例,方法很简单,就是将这个getInstance方法加锁,一个线程必须等待另外一个线程创建完成后才能使用这个方法,这就保证了单例的唯一性。

public class Person  // 推荐
    private static Person mInstance;

    public static Person getInstance(Context context) 
        if (null == mInstance) 
            synchronized (Person.class) 
                if (null == mInstance) 
                    mInstance = new Person();
                
            
        
        return mInstance;
    

public class Person 
    private static Person mInstance;

    public static synchronized Person getInstance(Context context) 
        if (null == mInstance) 
            mInstance = new Person();
        
        return mInstance;
    

   两个并发线程访问同一个对象obj中的synchronized修饰的一个方法时,一个时间内只能有一个线程得到执行,即A操作完才可以让B操作,否则B一直处于等待的状态中,也可以说是一种阻塞的状态。


synchronized优缺点

  • 优点是将解决多线程的问题,避免占用资源,占用多个对象。
  • 缺点是会锁住某一段程序,别的程序如果需要调用的话就必须等待,减少了速度、效率。有可能产生死锁,导致程序中断。

以上是关于单例模式与synchronized的主要内容,如果未能解决你的问题,请参考以下文章

单例模式与synchronized

多线程与单例模式

彻头彻尾理解单例模式与多线程

彻头彻尾理解单例模式与多线程

Java并发单例模式与synchronized关键字与voliate关键字

你见过这样的单例模式吗?