Head First 设计模式学习笔记 —— 单件模式

Head First 设计模式学习笔记 —— 单件模式

                                                                                                                                                                                   —— 只生一个孩儿
问题来源:
    如何确保一个类只有一个实例?
    单件模式让类来管理自己的一个实例,避免程序自行产生其他该类的实例。当需要该类的实例时,程序询问该类是否有实例,如果该类有实例,则返回该实例;如果该类无实例,则构造一个实例并返回,并在全局中维护这唯一的一个实例。总结来讲,单件模式就是只生一个“孩儿”。下面是经典单件模式的类图:
    
    Singleton.java代码如下:
public class Singleton {
    
    private static Singleton instance;
    public String name = "singleton";

    private Singleton() {}

    private Singleton(String name) {
        this.name = name;       
    }

    public static Singleton getInstance(String name) {
        if(instance == null) {
            instance = new Singleton(name);
        }
        return instance;
    }

    public void printName() {
        System.out.println("My name is : " + name);
    }

}
    Singleton类为了避免被公开实例化,因此将构造方法设为“私有的”,通过静态方法getInstance()判断Singleton类是否存在实例,如果存在实例,则直接返回,否则调用构造方法构造一个实例并返回。
    测试程序 test.java 代码如下:
import java.lang.reflect.Field;

public class test {
	public static void main(String[] args) {

    	Singleton singleton1 = Singleton.getInstance("singleton1");
        singleton1.printName();

        Singleton singleton2 = Singleton.getInstance("singleton2");
        singleton2.printName();    //singleton2 and singleton1 is the same object

        System.out.println(singleton1);
        System.out.println(singleton2);

    }
}
    test.java代码中,尽管调用了多次getInstance()方法,但是通过结果可以发现,程序中仅有一个Singleton实例。结果图如下:


    经典单件模式在多线程中就不适用了,因为对于经典单件模式,JVM并不能保证多个线程互斥地访问实例,因此多个线程可能会产生多个实例。解决的方法是同步各个线程,当一个线程访问实例时,保持对该实例的锁定,其他试图访问该实例的线程将被阻塞。
    按上述思路修改后的代码如下,Singleton.java:
public class Singleton {
    
    private volatile static Singleton instance;
    public String name = "singleton";

    private Singleton() {}

    private Singleton(String name) {
        this.name = name;       
    }

    public static Singleton getInstance(String name) {
        if(instance == null) {
	    synchronize (Singleton.class) { //对Singleton类进行同步
	        if(instance == null) {
		    instance = new Singleton(name);		
		}
	    }
        }
        return instance;
    }

    public void printName() {
        System.out.println("My name is : " + name);
    }

}
    上述代码中,使用volatile关键字修饰instance变量,保证其他线程在使用该变量时,都会读取变量最后一次修改后最新的值。synchronized关键字同步Singleton类,保证全局多个线程间对只有一个线程可以执行同步块内的代码。

参考自:



    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值