Coverage Report - com.ctrip.framework.apollo.core.utils.ApolloThreadFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
ApolloThreadFactory
0%
0/41
0%
0/10
2.125
ApolloThreadFactory$1
0%
0/2
0%
0/6
2.125
ApolloThreadFactory$ClassifyStandard
N/A
N/A
2.125
 
 1  
 package com.ctrip.framework.apollo.core.utils;
 2  
 
 3  
 import org.slf4j.Logger;
 4  
 import org.slf4j.LoggerFactory;
 5  
 
 6  
 import java.util.Arrays;
 7  
 import java.util.HashSet;
 8  
 import java.util.Set;
 9  
 import java.util.concurrent.ThreadFactory;
 10  
 import java.util.concurrent.TimeUnit;
 11  
 import java.util.concurrent.atomic.AtomicLong;
 12  
 
 13  
 public class ApolloThreadFactory implements ThreadFactory {
 14  0
   private static Logger log = LoggerFactory.getLogger(ApolloThreadFactory.class);
 15  
 
 16  0
   private final AtomicLong threadNumber = new AtomicLong(1);
 17  
 
 18  
   private final String namePrefix;
 19  
 
 20  
   private final boolean daemon;
 21  
 
 22  0
   private static final ThreadGroup threadGroup = new ThreadGroup("Apollo");
 23  
 
 24  
   public static ThreadGroup getThreadGroup() {
 25  0
     return threadGroup;
 26  
   }
 27  
 
 28  
   public static ThreadFactory create(String namePrefix, boolean daemon) {
 29  0
     return new ApolloThreadFactory(namePrefix, daemon);
 30  
   }
 31  
 
 32  
   public static boolean waitAllShutdown(int timeoutInMillis) {
 33  0
     ThreadGroup group = getThreadGroup();
 34  0
     Thread[] activeThreads = new Thread[group.activeCount()];
 35  0
     group.enumerate(activeThreads);
 36  0
     Set<Thread> alives = new HashSet<Thread>(Arrays.asList(activeThreads));
 37  0
     Set<Thread> dies = new HashSet<Thread>();
 38  0
     log.info("Current ACTIVE thread count is: {}", alives.size());
 39  0
     long expire = System.currentTimeMillis() + timeoutInMillis;
 40  0
     while (System.currentTimeMillis() < expire) {
 41  0
       classify(alives, dies, new ClassifyStandard<Thread>() {
 42  
         @Override
 43  
         public boolean satisfy(Thread thread) {
 44  0
           return !thread.isAlive() || thread.isInterrupted() || thread.isDaemon();
 45  
         }
 46  
       });
 47  0
       if (alives.size() > 0) {
 48  0
         log.info("Alive apollo threads: {}", alives);
 49  
         try {
 50  0
           TimeUnit.SECONDS.sleep(2);
 51  0
         } catch (InterruptedException ex) {
 52  
           // ignore
 53  0
         }
 54  
       } else {
 55  0
         log.info("All apollo threads are shutdown.");
 56  0
         return true;
 57  
       }
 58  
     }
 59  0
     log.warn("Some apollo threads are still alive but expire time has reached, alive threads: {}",
 60  
         alives);
 61  0
     return false;
 62  
   }
 63  
 
 64  
   private static interface ClassifyStandard<T> {
 65  
     boolean satisfy(T thread);
 66  
   }
 67  
 
 68  
   private static <T> void classify(Set<T> src, Set<T> des, ClassifyStandard<T> standard) {
 69  0
     Set<T> set = new HashSet<>();
 70  0
     for (T t : src) {
 71  0
       if (standard.satisfy(t)) {
 72  0
         set.add(t);
 73  
       }
 74  0
     }
 75  0
     src.removeAll(set);
 76  0
     des.addAll(set);
 77  0
   }
 78  
 
 79  0
   private ApolloThreadFactory(String namePrefix, boolean daemon) {
 80  0
     this.namePrefix = namePrefix;
 81  0
     this.daemon = daemon;
 82  0
   }
 83  
 
 84  
   public Thread newThread(Runnable runnable) {
 85  0
     Thread thread = new Thread(threadGroup, runnable,//
 86  0
         threadGroup.getName() + "-" + namePrefix + "-" + threadNumber.getAndIncrement());
 87  0
     thread.setDaemon(daemon);
 88  0
     if (thread.getPriority() != Thread.NORM_PRIORITY) {
 89  0
       thread.setPriority(Thread.NORM_PRIORITY);
 90  
     }
 91  0
     return thread;
 92  
   }
 93  
 }