23种常见设计模式之一:饿汉单例
怎样构造一个单例呢?
- 私有构造方法
- 静态成员变量
- 对外的静态方法获取成员变量
第一步:写一个单例类
public class Singleton implements Serializable {
//当前类的示例属性
private static Singleton instance = new Singleton();
//私有化构造器
private Singleton(){
}
//对外提供共有的,获取当前对象的方法
public static Singleton getInstance(){
return instance;
}
}
第二步:测试类
- 用多线程创造20个单例对象,看看他们是否是同一个(是同一个)
- 通过反射的方法来创造对象,是同一个对象吗(不是同一个对象)
- 将单例类对象序列化到文件中,再反序列到内存,和之前还是同一个对象吗(不是同一个对象)
public class Test {
public static void main(String[] args) throws Exception {
// test1();
// test2();
test3();
}
//通过多线程查看,20个单例是否是同一个对象
public static void test1(){
for (int i = 0; i < 20; i++) {
new Thread(new Runnable() {
@Override
public void run() {
Singleton instance = Singleton.getInstance();
System.out.println(instance);
}
}).start();
}
}
//饿汉单例对通过反射来说不安全,获取的是多个对象
public static void test2() throws Exception{
Class<Singleton> singletonClass = Singleton.class;
Constructor<Singleton> constructor = singletonClass.getDeclaredConstructor();
constructor.setAccessible(true);
Singleton singleton = constructor.newInstance();
Singleton singleton2 = constructor.newInstance();
System.out.println(singleton==singleton2); //false,拿到两个不同对象
}
//对象的序列化
public static void serialize(Singleton singleton){
ObjectOutputStream objectOutputStream = null;
try {
FileOutputStream fileOutputStream = new FileOutputStream(new File("/Users/mima000000/Desktop/res.txt"));
objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(singleton);
objectOutputStream.flush();
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
objectOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 对象的反序列化
public static Object unserialize() {
ObjectInputStream objectInputStream = null;
try{
FileInputStream fileInputStream = new FileInputStream(new File("/Users/mima000000/Desktop/res.txt"));
objectInputStream = new ObjectInputStream(fileInputStream);
Object o = objectInputStream.readObject();
return o;
}catch (Exception e){
e.printStackTrace();
}finally {
try {
objectInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
//饿汉单例序列化后,再反序列化,不是同一个对象
public static void test3(){
//拿到对象
Singleton instance = Singleton.getInstance();
// 序列化
// serialize(instance);
Object unserialize = unserialize();
Singleton s1 = (Singleton)unserialize;
System.out.println(instance==s1); //false,已经不是同一个对象
}
}