设计模式---------单例模式

来源:互联网 发布:15寸mac魔兽世界 编辑:程序博客网 时间:2024/06/03 22:42

单例模式:确保一个类只有一个实例,自行实例化并向系统提供这个实例。

/** * 线程不安全方式。 */public class Singleton {    private static Singleton singleton;    //防止外部类实现    private Singleton() {    }    public static Singleton getInstance(){        if(singleton==null){            singleton=new Singleton();        }        return singleton;    }}

我们用两个线程测试该单例模式的安全性:

public class SingleThread  implements  Runnable{    @Override    public void run() {        Singleton singleton=Singleton.getInstance();        System.out.println(singleton);    }}
public class TestA {    public static void main(String[] args) {        Thread t1=new Thread(new SingleThread());        Thread t2=new Thread(new SingleThread());        t1.start();        t2.start();    }}

这里写图片描述

这里写图片描述

结果分析:
当线程t1执行到if(singleton==null)时,去创建对象,但是对象并未创建好时,t2也同时执行到if语句。此时的singleton为null,t2也去new这个对象,因此这两个对象不是用一个。

饿汉式单例:

public class EagerSingleton {    private static final EagerSingleton single=new EagerSingleton();    private EagerSingleton(){    }    public static EagerSingleton getInstance(){        return single;    }}

缺点:不能实现延迟加载。在类初始化时single对象就会被初始化。

懒汉式单例模式:

public class LazySingleton {    private static LazySingleton singleton=null;    private LazySingleton() {    }    public synchronized static LazySingleton getInstance(){        if(singleton==null){            singleton=new LazySingleton();        }        return singleton;    }}

缺点:对于多线程状态下,我们每个线程执行时都要等待上一个线程释放这个锁。我们只需对创建这个对象时加锁就行

public class LazySingleton {    private static LazySingleton singleton=null;    private LazySingleton() {    }    public synchronized static LazySingleton getInstance(){        if(singleton==null){            synchronized(LazySingleton.class) {                singleton = new LazySingleton();            }        }        return singleton;    }}

缺点:这个是线程非安全的。当线程1进入到该同步代码块中,1执行完,2进入到代码块,此时2线程并不知道1已经创建好,于是又创建线程。
因此我们可以采用双重检查锁定来实现:

public class LazySingleton {    private volatile static LazySingleton singleton=null;    private LazySingleton() {    }    public synchronized static LazySingleton getInstance(){    //第一次判断        if(singleton==null){            synchronized(LazySingleton.class) {            //第二次判断                if(singleton==null) {                    singleton = new LazySingleton();                }            }        }        return singleton;    }}
原创粉丝点击