单例模式
饿汉模式
public class HungrySingleton {
private HungrySingleton() {
}
private static HungrySingleton instance = new HungrySingleton();
public static HungrySingleton getInstance() {
return instance;
}
}
懒汉模式
public class IdlerSingleton {
private IdlerSingleton() {
}
private static IdlerSingleton instance;
public static IdlerSingleton getInstance() {
// 双检索
if (instance == null){
// 假设有100个线程同时getInstance, 为保持最终只new一次,new的过程要加锁。
synchronized (IdlerSingleton.class){
// 可能多个线程在竞争锁,第一个线程已经实例化了instance以后,第二个线程又拿到了锁,准备第二次实例化,这时候要如果非null,应直接返回
if (instance == null){
instance = new IdlerSingleton();
}
}
}
return instance;
}
}
即使如此,你已经手撸了又检索的懒汉单例模式和饿汉模式,但强大无敌的面试官还是不满意,他们又问了:
即使这样,就一定会线程安全并且instance只被实例化一次吗?如果一个应用存在多个classLoader,类对象被加载了多次呢?
原型模式
public class Prototype implements Cloneable, Serializable {
private Goods goods;
private String name;
@Override
protected Prototype clone() throws CloneNotSupportedException {
System.out.println("对象被浅克隆----");
return (Prototype) super.clone();
}
public Prototype deepClone() throws IOException, ClassNotFoundException {
//将对象写入bos
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (Prototype) ois.readObject();
}
public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
Prototype p = new Prototype();
p.setName("张三");
Goods goods = new Goods();
goods.setName("冰糖雪梨");
p.setGoods(goods);
System.out.println("原对象的hash: " + Objects.hash(p));
System.out.println("-原对象goods的hash: " + Objects.hash(goods));
// 浅克隆对象
Prototype shallowCopy = p.clone();
System.out.println("浅克隆对象的hash: " + Objects.hash(shallowCopy));
System.out.println("-浅对象goods的hash: " + Objects.hash(shallowCopy.getGoods()));
System.out.println(shallowCopy.getGoods().getName());
// 深克隆对象
Prototype deepCopy = p.deepClone();
System.out.println("深克隆对象的hash: " + Objects.hash(deepCopy));
System.out.println("-深对象goods的hash: " + Objects.hash(deepCopy.getGoods()));
System.out.println(deepCopy.getGoods().getName());
}
}