饿汉式单例模式

  1. // 饿汉式单例
  2. public class Hungry {
  3. // 可能会浪费空间
  4. private Hungry(){}
  5. private final static Hungry HUNGRY = new Hungry();
  6. public static Hungry getInstance(){
  7. return HUNGRY;
  8. }
  9. }

这种方式实现的很简单,用很明显的延迟初始化但是线程不安全不支持多线程访问,严格来说并不是一个单例模式

线程安全的饿汉单例模式

  1. import com.sun.corba.se.impl.orbutil.CorbaResourceUtil;
  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.Field;
  4. // 懒汉式单例
  5. // 道高一尺,魔高一丈!
  6. public class LazyMan {
  7. private static boolean qinjiang = false;
  8. private LazyMan(){
  9. synchronized (LazyMan.class){
  10. if (qinjiang == false){
  11. qinjiang = true;
  12. }
  13. else {
  14. throw new RuntimeException("不要试图使用反射破坏异常");
  15. }
  16. }
  17. } private volatile static LazyMan lazyMan;
  18. // 双重检测锁模式的 懒汉式单例 DCL懒汉式
  19. public static LazyMan getInstance(){
  20. if (lazyMan==null){
  21. synchronized (LazyMan.class){
  22. if (lazyMan==null){
  23. lazyMan = new LazyMan(); // 不是一个原子性操作
  24. }
  25. }
  26. }
  27. return lazyMan;
  28. }
  29. // 反射!
  30. public static void main(String[] args) throws Exception {
  31. // LazyMan instance = LazyMan.getInstance();
  32. Field qinjiang = LazyMan.class.getDeclaredField("qinjiang");
  33. qinjiang.setAccessible(true);
  34. Constructor<LazyMan> declaredConstructor =
  35. LazyMan.class.getDeclaredConstructor(null);
  36. declaredConstructor.setAccessible(true);
  37. LazyMan instance = declaredConstructor.newInstance();
  38. qinjiang.set(instance,false);
  39. LazyMan instance2 = declaredConstructor.newInstance();
  40. System.out.println(instance);
  41. System.out.println(instance2);
  42. }
  43. }

但是这种方法无法避免通过反射改变标志位从而破解单例模式

静态内部类实现单例模式

  1. public class person{
  2. private person(){}
  3. public static person getinstance(){
  4. }
  5. public static class per(){
  6. private final static person person=new person();
  7. }
  8. }

使用枚举来实现单例模式

代码块
image.png