单例模式学习笔记

来源:互联网 发布:appstore代充淘宝 编辑:程序博客网 时间:2024/05/18 03:47



单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问他的全局访问点,通常我们可以让一个全局变量使得一个对象被访问,但他不能防止你实例化多个对象。一个最好的办法就是,让类自身负责保存他的唯一实例。这
个类可以保证没有其他实例可以被创建,并且他可以提供一个访问该实例的方法。

个类可以保证没有其他实例可以被创建,并且他可以提供一个访问该实例的方法。

所有类都有构造方法,不编码则系统默认生成空的构造方法,如重写构造方法,则默认的构造方法就会失效。


public class Singleton {    /**     *利用一个静态变量记录Singleton类的唯一实例。如果没有“static”修饰,下面的     *getSingleton()方法不能引用非静态变量singleton。“volatile”修饰符     *保证了内存可见,即如果该变量有变化(这里的变化就是被实例化),     *多个线程能及时看到singleton变量的变化。     */    private volatile static Singleton singleton;    //构造私有的构造函数,只有在Singleton类内才可以调用     private Singleton() {}    //getSingleton()方法提供了一个全局访问点    public static Singleton getSingleton() {        //利用双重锁,首先检查实例是否已经创建,如果没有创建才进行同步,        //如果创建过就直接返回,不需要加锁。        //如果对整个方法使用synchronized加锁则会造成效率降低。        if (singleton == null) {            synchronized (Singleton.class) {                /**                 *如果为空,就利用私有的构造函数产生一个Singleton实例并把它赋值到singleton                 *静态变量中 */                                if (singleton == null) {                    singleton = new Singleton();                }            }        }        //如果不为空,就表示之前已经创建过实例,并将singleton当做返回值        return singleton;    }    public void add() {        System.out.println("add");    }    public static void main(String[] args) {        //创建实例        Singleton sing = Singleton.getSingleton();        Singleton sing2 = Singleton.getSingleton();        sing.add();        sing2.add();        //用“==”判断实例是否指向相同对象        System.out.println("sing == sing2: " + (sing == sing2));    }}运行结果:addaddsing == sing2: true     //通过结果可以看出两个引用指向同一对象

这是在同一个类中创建main()方法,如果在另外一个类中创建


public class Singleton {    private volatile static Singleton singleton;    private Singleton() {}    public static Singleton getSingleton() {        if (singleton == null) {            synchronized (Singleton.class) {                if (singleton == null) {                    singleton = new Singleton();                }            }        }        return singleton;    }    public void add() {        System.out.println("add");    }}class MainTest {    public static void main(String[] args) {    /**    *语句不能通过编译,就保证了类的单一实例。    */    //Singleton test3 = Singleton.singleton;      //getSingleton()方法时静态的,就可以在代码的任何地方使用Singleton.getSingleton()        Singleton test1 = Singleton.getSingleton();        Singleton test2 = Singleton.getSingleton();        //Singleton test4 = Singleton.singleton;        test1.add();        //test3.add();        System.out.println("test1 == test2: " + (test1 == test2));        //System.out.println("test3 == test4: " + (test3 == test4));        //System.out.println("test1 == test3: " + (test1 == test3));        //System.out.println("test1 == test4: " + (test1 == test4));    }}运行结果:E:\test-git\Thread>javac Singleton.java//编译时会编译出两个class文件,因为main方法在MainTest.class中,所有运行时用java MainTest E:\test-git\Thread>java MainTestaddtest1 == test2: true

“private volatile static Singleton singleton”中的private修饰符如果该为public就不能保证
类的唯一实例。


public class Singleton {    public volatile static Singleton singleton;    private Singleton() {}    public static Singleton getSingleton() {        if (singleton == null) {            synchronized (Singleton.class) {                if (singleton == null) {                    singleton = new Singleton();                }            }        }        return singleton;    }    public void add() {        System.out.println("add");    }}class MainTest {    public static void main(String[] args) {    Singleton test3 = Singleton.singleton;      //getSingleton()方法时静态的,就可以在代码的任何地方使用Singleton.getSingleton()        Singleton test1 = Singleton.getSingleton();        Singleton test2 = Singleton.getSingleton();        Singleton test4 = Singleton.singleton;        test1.add();        //test3.add();   如果加上运行时会报异常,引用了空指针        System.out.println("test1 == test2: " + (test1 == test2));        System.out.println("test3 == test4: " + (test3 == test4));        System.out.println("test1 == test3: " + (test1 == test3));        System.out.println("test1 == test4: " + (test1 == test4));    }}运行结果:addtest1 == test2: true   // 从这看出test1和test2是指向同一个对象的test3 == test4: false   // 从下面三句可以看出test3和test1、test2、test4的引用不同。test1 == test3: false   //从“test3.add();”看出test3为null。 test1 == test4: true


0 0
原创粉丝点击