饿汉式(推荐使用)

  1. /**
  2. * 饿汉式
  3. * 类加载到内存后,就实例化一个单例,JVM保证线程安全
  4. * 简单实用,推荐使用!
  5. * 唯一缺点:不管用到与否,类装载时就完成实例化
  6. * Class.forName("")
  7. * (话说你不用的,你装载它干啥)
  8. */
  9. public class Mgr01 {
  10. private static final Mgr01 INSTANCE = new Mgr01();
  11. private Mgr01() {};
  12. public static Mgr01 getInstance() {
  13. return INSTANCE;
  14. }
  15. public void m() {
  16. System.out.println("m");
  17. }
  18. public static void main(String[] args) {
  19. Mgr01 m1 = Mgr01.getInstance();
  20. Mgr01 m2 = Mgr01.getInstance();
  21. System.out.println(m1 == m2);
  22. }
  23. }
  1. /**
  2. * 跟上面的一个意思
  3. */
  4. public class Mgr02 {
  5. private static final Mgr02 INSTANCE;
  6. static {
  7. INSTANCE = new Mgr02();
  8. }
  9. private Mgr02() {};
  10. public static Mgr02 getInstance() {
  11. return INSTANCE;
  12. }
  13. public void m() {
  14. System.out.println("m");
  15. }
  16. public static void main(String[] args) {
  17. Mgr02 m1 = Mgr02.getInstance();
  18. Mgr02 m2 = Mgr02.getInstance();
  19. System.out.println(m1 == m2);
  20. }
  21. }

懒汉式

一、

  1. /**
  2. * lazy loading
  3. * 也称懒汉式
  4. * 虽然达到了按需初始化的目的,但却带来线程不安全的问题
  5. */
  6. public class Mgr03 {
  7. private static Mgr03 INSTANCE;
  8. private Mgr03() {
  9. }
  10. public static Mgr03 getInstance() {
  11. if (INSTANCE == null) {
  12. try {
  13. Thread.sleep(1);
  14. } catch (InterruptedException e) {
  15. e.printStackTrace();
  16. }
  17. INSTANCE = new Mgr03();
  18. }
  19. return INSTANCE;
  20. }
  21. public void m() {
  22. System.out.println("m");
  23. }
  24. public static void main(String[] args) {
  25. for(int i=0; i<100; i++) {
  26. new Thread(()->
  27. System.out.println(Mgr03.getInstance().hashCode())
  28. ).start();
  29. }
  30. }
  31. }

二、

  1. /**
  2. * lazy loading
  3. * 也称懒汉式
  4. * 虽然达到了按需初始化的目的,但却带来线程不安全的问题
  5. * 可以通过synchronized解决,但也带来效率下降
  6. */
  7. public class Mgr04 {
  8. private static Mgr04 INSTANCE;
  9. private Mgr04() {
  10. }
  11. public static synchronized Mgr04 getInstance() {
  12. if (INSTANCE == null) {
  13. try {
  14. Thread.sleep(1);
  15. } catch (InterruptedException e) {
  16. e.printStackTrace();
  17. }
  18. INSTANCE = new Mgr04();
  19. }
  20. return INSTANCE;
  21. }
  22. public void m() {
  23. System.out.println("m");
  24. }
  25. public static void main(String[] args) {
  26. for(int i=0; i<100; i++) {
  27. new Thread(()->{
  28. System.out.println(Mgr04.getInstance().hashCode());
  29. }).start();
  30. }
  31. }
  32. }

三、

  1. /**
  2. * lazy loading
  3. * 也称懒汉式
  4. * 虽然达到了按需初始化的目的,但却带来线程不安全的问题
  5. * 可以通过synchronized解决,但也带来效率下降
  6. */
  7. public class Mgr05 {
  8. private static Mgr05 INSTANCE;
  9. private Mgr05() {
  10. }
  11. public static Mgr05 getInstance() {
  12. if (INSTANCE == null) {
  13. //妄图通过减小同步代码块的方式提高效率,然后不可行
  14. synchronized (Mgr05.class) {
  15. try {
  16. Thread.sleep(1);
  17. } catch (InterruptedException e) {
  18. e.printStackTrace();
  19. }
  20. INSTANCE = new Mgr05();
  21. }
  22. }
  23. return INSTANCE;
  24. }
  25. public void m() {
  26. System.out.println("m");
  27. }
  28. public static void main(String[] args) {
  29. for(int i=0; i<100; i++) {
  30. new Thread(()->{
  31. System.out.println(Mgr05.getInstance().hashCode());
  32. }).start();
  33. }
  34. }
  35. }

四、

  1. /**
  2. * lazy loading
  3. * 也称懒汉式
  4. * 虽然达到了按需初始化的目的,但却带来线程不安全的问题
  5. * 可以通过synchronized解决,但也带来效率下降
  6. */
  7. public class Mgr06 {
  8. private static volatile Mgr06 INSTANCE; //JIT
  9. private Mgr06() {
  10. }
  11. public static Mgr06 getInstance() {
  12. if (INSTANCE == null) {
  13. //双重检查
  14. synchronized (Mgr06.class) {
  15. if(INSTANCE == null) {
  16. try {
  17. Thread.sleep(1);
  18. } catch (InterruptedException e) {
  19. e.printStackTrace();
  20. }
  21. INSTANCE = new Mgr06();
  22. }
  23. }
  24. }
  25. return INSTANCE;
  26. }
  27. public void m() {
  28. System.out.println("m");
  29. }
  30. public static void main(String[] args) {
  31. for(int i=0; i<100; i++) {
  32. new Thread(()->{
  33. System.out.println(Mgr06.getInstance().hashCode());
  34. }).start();
  35. }
  36. }
  37. }

静态内部类方式实现懒加载

  1. /**
  2. * 静态内部类方式
  3. * JVM保证单例
  4. * 加载外部类时不会加载内部类,这样可以实现懒加载
  5. */
  6. public class Mgr07 {
  7. private Mgr07() {
  8. }
  9. private static class Mgr07Holder {
  10. private final static Mgr07 INSTANCE = new Mgr07();
  11. }
  12. public static Mgr07 getInstance() {
  13. return Mgr07Holder.INSTANCE;
  14. }
  15. public void m() {
  16. System.out.println("m");
  17. }
  18. public static void main(String[] args) {
  19. for(int i=0; i<100; i++) {
  20. new Thread(()->{
  21. System.out.println(Mgr07.getInstance().hashCode());
  22. }).start();
  23. }
  24. }
  25. }

枚举(很少使用)

  1. /**
  2. * 不仅可以解决线程同步,还可以防止反序列化。
  3. */
  4. public enum Mgr08 {
  5. INSTANCE;
  6. public void m() {}
  7. public static void main(String[] args) {
  8. for(int i=0; i<100; i++) {
  9. new Thread(()->{
  10. System.out.println(Mgr08.INSTANCE.hashCode());
  11. }).start();
  12. }
  13. }
  14. }