单例模式

饿汉模式

  1. public class HungrySingleton {
  2. private HungrySingleton() {
  3. }
  4. private static HungrySingleton instance = new HungrySingleton();
  5. public static HungrySingleton getInstance() {
  6. return instance;
  7. }
  8. }

懒汉模式

  1. public class IdlerSingleton {
  2. private IdlerSingleton() {
  3. }
  4. private static IdlerSingleton instance;
  5. public static IdlerSingleton getInstance() {
  6. // 双检索
  7. if (instance == null){
  8. // 假设有100个线程同时getInstance, 为保持最终只new一次,new的过程要加锁。
  9. synchronized (IdlerSingleton.class){
  10. // 可能多个线程在竞争锁,第一个线程已经实例化了instance以后,第二个线程又拿到了锁,准备第二次实例化,这时候要如果非null,应直接返回
  11. if (instance == null){
  12. instance = new IdlerSingleton();
  13. }
  14. }
  15. }
  16. return instance;
  17. }
  18. }

即使如此,你已经手撸了又检索的懒汉单例模式和饿汉模式,但强大无敌的面试官还是不满意,他们又问了:
即使这样,就一定会线程安全并且instance只被实例化一次吗?如果一个应用存在多个classLoader,类对象被加载了多次呢?

原型模式

  1. public class Prototype implements Cloneable, Serializable {
  2. private Goods goods;
  3. private String name;
  4. @Override
  5. protected Prototype clone() throws CloneNotSupportedException {
  6. System.out.println("对象被浅克隆----");
  7. return (Prototype) super.clone();
  8. }
  9. public Prototype deepClone() throws IOException, ClassNotFoundException {
  10. //将对象写入bos
  11. ByteArrayOutputStream bos = new ByteArrayOutputStream();
  12. ObjectOutputStream oos = new ObjectOutputStream(bos);
  13. oos.writeObject(this);
  14. ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
  15. ObjectInputStream ois = new ObjectInputStream(bis);
  16. return (Prototype) ois.readObject();
  17. }
  18. public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
  19. Prototype p = new Prototype();
  20. p.setName("张三");
  21. Goods goods = new Goods();
  22. goods.setName("冰糖雪梨");
  23. p.setGoods(goods);
  24. System.out.println("原对象的hash: " + Objects.hash(p));
  25. System.out.println("-原对象goods的hash: " + Objects.hash(goods));
  26. // 浅克隆对象
  27. Prototype shallowCopy = p.clone();
  28. System.out.println("浅克隆对象的hash: " + Objects.hash(shallowCopy));
  29. System.out.println("-浅对象goods的hash: " + Objects.hash(shallowCopy.getGoods()));
  30. System.out.println(shallowCopy.getGoods().getName());
  31. // 深克隆对象
  32. Prototype deepCopy = p.deepClone();
  33. System.out.println("深克隆对象的hash: " + Objects.hash(deepCopy));
  34. System.out.println("-深对象goods的hash: " + Objects.hash(deepCopy.getGoods()));
  35. System.out.println(deepCopy.getGoods().getName());
  36. }
  37. }