单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意:

  • 1、单例类只能有一个实例。
  • 2、单例类必须自己创建自己的唯一实例。
  • 3、单例类必须给所有其他对象提供这一实例。

饿汉模式

  1. /**
  2. * @author meikb
  3. * @desc 饿汉模式 是 类加载就初始化 无需考虑多线程
  4. * @date 2020-04-24 15:40
  5. */
  6. public class SingleEager {
  7. private SingleEager(){}
  8. private static SingleEager singleEager = new SingleEager();
  9. public static SingleEager getObject(){
  10. return singleEager;
  11. }
  12. }

懒汉模式

  1. /**
  2. * @author meikb
  3. * @desc 多线程有问题
  4. * @date 2020-05-23 10:28
  5. */
  6. public class SingleLazy {
  7. private SingleLazy(){}
  8. private static SingleLazy singleLazy = null;
  9. public static SingleLazy getObject(){
  10. if(null == singleLazy){
  11. singleLazy = new SingleLazy();
  12. }
  13. return singleLazy;
  14. }
  15. }

懒汉多线程

  1. /**
  2. * @author meikb
  3. * @desc
  4. * @date 2020-05-23 10:28
  5. */
  6. public class SingleLazy2 {
  7. private SingleLazy2(){}
  8. private static volatile SingleLazy2 singleLazy = null;
  9. //如果有100个线程,那只有第一个需要加 synchronized 其他线程按理说不需要加锁,所以效率比较低
  10. public static synchronized SingleLazy2 getObject2(){
  11. if(null == singleLazy){
  12. singleLazy = new SingleLazy2();
  13. }
  14. return singleLazy;
  15. }
  16. //如果有100个线程
  17. public static SingleLazy2 getObject(){
  18. if(null == singleLazy){
  19. //10个线程判断到singleLazy 为null
  20. //初始化加锁 只有一个线程 能获取锁 继续执行
  21. synchronized (SingleLazy2.class){
  22. //第一个线程直线完成后,后面的线程继续执行,这个时候 singleLazy 不为空,所以要判断是否为空
  23. if(null == singleLazy){
  24. singleLazy = new SingleLazy2();
  25. }
  26. }
  27. }
  28. return singleLazy;
  29. }
  30. }

测试主函数

  1. /**
  2. * @author meikb
  3. * @desc
  4. * @date 2020-05-23 10:38
  5. */
  6. public class SingleMain {
  7. public static void main(String[] args) {
  8. CountDownLatch countDownLatch = new CountDownLatch(1);
  9. for (int i = 0; i < 100; i++) {
  10. new Thread(new Runnable() {
  11. @Override
  12. public void run() {
  13. try {
  14. countDownLatch.await();
  15. } catch (InterruptedException e) {
  16. e.printStackTrace();
  17. }
  18. SingleLazy2 singleLazy2 = SingleLazy2.getObject();
  19. System.out.println(singleLazy2);
  20. }
  21. }).start();
  22. }
  23. countDownLatch.countDown();
  24. }
  25. }