单例模式
饿汉模式
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;@Overrideprotected Prototype clone() throws CloneNotSupportedException {System.out.println("对象被浅克隆----");return (Prototype) super.clone();}public Prototype deepClone() throws IOException, ClassNotFoundException {//将对象写入bosByteArrayOutputStream 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());}}
