单例模式中的同步锁

来源:互联网 发布:机械设计自动画图软件 编辑:程序博客网 时间:2024/06/05 00:52

单例模式的编写有多种方式,但是有些细节的地方容易被大家忽略,在这里我简单的向大家分享一下,如有不正确的地方,还望指正。

经典的单例模式有两种方式一种是饿汉式,一种是懒汉式。

先来提一下饿汉式,这个是最简单但是最不实用的。

public class SingleTone {private SingleTone(){}private static SingleTone single = null;//饿汉式public static SingleTone getInstance(){single = new SingleTone();return single;}}

下面是比较简单的懒汉式编写,主要是为了保证创建的对象只有一个。

public class SingleTone {private SingleTone(){}private static SingleTone single = null;//懒汉式public static SingleTone getInstance(){if(single==null){single = new SingleTone();}return single;}}

这种懒汉式存在线程安全问题,所以需要加同步锁,加同步锁,则有两种方式,一种是将synchronized加在方法上,另一种是将synchronized加在方法内。

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

但是,synchronized加在方法会使效率低,因为锁的范围比较大,我们要向保证是单例的,其实主要是为了保证single = new SingleTone();是线程安全的就行,所以在加锁的时候,我们一般会将锁加到方法里面。

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

将锁加到里面后又会有新的问题,如果两个线程同时进入了getInstence()中后,并都判断了single等于null,其中一个进入同步锁中,另外一个在门口等待,当一个创建完对象后让出锁,另一个直接进去,这样它就会又创建对象,所以更好的方式是加双重锁定,这种方式是效率高,并且安全。

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


原创粉丝点击