设计模式之---单例模式和多线程

in #steemit7 years ago (edited)


单例模式是23个设计模式中比较简单,也是最常用的模式之一,虽然简单,但在多线程并发访问时如果不注意一些使用细节,会引发意想不到的bug。

单例模式

定义:保证一个类只有一个实例,并且自行实例化并向整个系统提供这个实例。
类图:待完成
优点:

  • 减少内存开支
  • 减少性能开销
  • 避免对资源的多重占用
  • 提供和共享全局访问量
    缺点:
  • 扩展性差
  • 测试不方便
  • 单例模式和单一职责莫设计原则向冲突

单例的两种使用形式

饿汉模式


public class EagerSingleton {
    private static EagerSingleton singleton=new EagerSingleton();
 private EagerSingleton(){

    }
    public static EagerSingleton getSingleton(){
        return singleton;
  }

}

懒汉模式

该代码采用了DCL双锁检测(double checked locking),避免了因为多线程并发下可能出现的异常

  public class LazySingleton {
    private volatile static LazySingleton singleton;
 private LazySingleton(){

    }
    public static LazySingleton getSingleton() throws InterruptedException {
        if (singleton != null) {

        } else {
            Thread.sleep(3000);
 synchronized (LazySingleton.class) {
                if (singleton == null) {
                    singleton = new LazySingleton();
  }
            }
        }
        return singleton;
  }
}

测试类:

  public class MyThread extends Thread{
    @Override
  public void run() {
        super.run();
  System.out.println("EagerSingleton"+EagerSingleton.getSingleton().hashCode());
 try {
            System.out.println("LazySingleton"+LazySingleton.getSingleton().hashCode());
  } catch (InterruptedException e) {
            e.printStackTrace();
  }
    }
}
public class Test {
    public static void main(String[] args) {
        MyThread t1=new MyThread();
  MyThread t2=new MyThread();
  MyThread t3=new MyThread();
  MyThread t4=new MyThread();
  t1.start();
  t2.start();
  t3.start();
  t4.start();
  }

}

运行结果

EagerSingleton908288934
EagerSingleton908288934
EagerSingleton908288934
EagerSingleton908288934
LazySingleton1515217202
LazySingleton1515217202
LazySingleton1515217202
LazySingleton1515217202

可以看到hash值相同,证明了我们的结论,试着把双重检查中的判空代码去掉,再运行下结果,你会发现单例失效了!
懒汉模式的使用比较多,我们可以使用一些技巧,对懒汉模式进行封装
代码如下:

public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}

可以看到,这是一个基于单例的模版类,使用方法也很简单,继承此类,提供约束的泛型,实现create()方法即可

Sort:  

Congratulations @hiquanta! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

You got your First payout

Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here

If you no longer want to receive notifications, reply to this comment with the word STOP

By upvoting this notification, you can help all Steemit users. Learn how here!

wow it's funny thing

Congratulations @hiquanta! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

You published a post every day of the week

Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here

If you no longer want to receive notifications, reply to this comment with the word STOP

By upvoting this notification, you can help all Steemit users. Learn how here!

Coin Marketplace

STEEM 0.20
TRX 0.12
JST 0.028
BTC 64453.36
ETH 3507.44
USDT 1.00
SBD 2.56