单例模式有以下特征:
- 只有一个对象存在
- 对象的实例化必须在类中实现
一、懒汉模式(线程不安全)
package com.kevin; // 懒汉模式 调用静态方法的时候实例化 public class Singleton1 { private String name = "lazy"; private Singleton1() { } private static Singleton1 single = null; //静态工厂方法 public static Singleton1 getInstance() { if (single == null) { single = new Singleton1(); } return single; } // 线程安全 /*public static synchronized Singleton getInstance() { if (single == null) { single = new Singleton(); } return single; }*/ // 双重检查锁定 /*public static Singleton getInstance() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; }*/ public String getName() { return name; } public void setName(String name) { this.name = name; } public void printInfo() { System.out.println("the name is " + name); } }
二、饿汉模式(线程安全,在类加载的时候完成实例化操作)
package com.kevin; // 饿汉模式 类加载的时候实例化 public class Singleton2 { private Singleton2() { } private static final Singleton2 single = new Singleton2(); //静态工厂方法 public static Singleton2 getInstance() { return single; } }
三、测试类
package com.kevin; import java.io.Serializable; // test singleton function // 饿汉式天生就是线程安全的,可以直接用于多线程而不会出现问题, // 懒汉式本身是非线程安全的 // 单例模式特点
// 只有一个实例存在
public class MainTest implements Serializable {
public static void main(String[] args) { test2(); } private static void test1() { Singleton1 s1 = Singleton1.getInstance(); s1.setName("22222"); s1.printInfo();; Singleton1 s2 = Singleton1.getInstance(); // 输出name的值,是s1的name的值 s2.printInfo(); s2.setName("33333"); // 设置s2的name的值,s1的name值已经变化 s1.printInfo(); } private static void test2() { Singleton1 s1 = Singleton1.getInstance(); s1.setName("aaaa"); Singleton1 s2 = Singleton1.getInstance(); s2.setName("bbbbb"); System.out.println(s1 == s2); } }