content: package io.bitchat.http.maker;
  
  import cn.hutool.core.util.ReflectUtil;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import java.util.Map;
  import java.util.concurrent.ConcurrentHashMap;
  import java.util.concurrent.locks.Lock;
  import java.util.concurrent.locks.ReentrantLock;
  
  /**
   * @author houyi
   **/
  public class HtmlMakerFactory {
  
      private volatile static HtmlMakerFactory factory;
  
      private Map<HtmlMakerEnum, HtmlMaker> htmlMakerMap;
  
      private final Lock lock;
  
      private HtmlMakerFactory() {
          htmlMakerMap = new ConcurrentHashMap<>();
          lock = new ReentrantLock();
      }
  
      /**
       * 获取工厂实例
       */
      public static HtmlMakerFactory instance() {
          if (factory == null) {
              synchronized (HtmlMakerFactory.class) {
                  if (factory == null) {
                      factory = new HtmlMakerFactory();
                  }
              }
          }
          return factory;
      }
  
      /**
       * 创建HtmlMaker实例
       */
      public HtmlMaker build(HtmlMakerEnum type, Class<? extends HtmlMaker> clazz) {
          if (type == null) {
              return null;
          } else {
              HtmlMaker htmlMaker = htmlMakerMap.get(type);
              if (htmlMaker == null) {
                  lock.lock();
                  try {
                      if (!htmlMakerMap.containsKey(type)) {
                          htmlMaker = ReflectUtil.newInstance(clazz);
                          htmlMakerMap.putIfAbsent(type, htmlMaker);
                      } else {
                          htmlMaker = htmlMakerMap.get(type);
                      }
                  } finally {
                      lock.unlock();
                  }
              }
              return htmlMaker;
          }
      }
  
      public static void main(String[] args) {
          int loopTimes = 200;
  
          class Runner implements Runnable {
  
              private Logger logger = LoggerFactory.getLogger(Runner.class);
  
              @Override
              public void run() {
                  HtmlMakerFactory factory = HtmlMakerFactory.instance();
                  logger.info("factory={},currentThread={}", (factory != null ? factory.getClass().getName() : "null"), Thread.currentThread().getName());
              }
          }
  
          for (int i = 0; i < loopTimes; i++) {
              new Thread(new Runner()).start();
          }
      }
  
  }
  