package com.yammer.metrics.util;

import java.util.concurrent.*;

public class ThreadPools
{
    private final ConcurrentMap<String, ScheduledExecutorService> threadPools =
            new ConcurrentHashMap<String, ScheduledExecutorService>(100);

    /**
     * Creates a new scheduled thread pool of a given size with the given name,
     * or returns an existing thread pool if one was already created with the
     * same name.
     *
     * @param poolSize the number of threads to create
     * @param name the name of the pool
     * @return a new {@link ScheduledExecutorService}
     */
    public ScheduledExecutorService newScheduledThreadPool(int poolSize, String name) {
        final ScheduledExecutorService existing = threadPools.get(name);
        if (existing == null) {
            // We lock here because executors are expensive to create.
            synchronized (threadPools) {
                final ScheduledExecutorService service = Executors.newScheduledThreadPool(poolSize, new NamedThreadFactory(name));
                threadPools.put(name, service);
                return service;
            }
        } else {
            return existing;
        }
    }

    /**
     * Shuts down all thread pools created by this class in an orderly fashion.
     */
    public void shutdownThreadPools() {
        synchronized (threadPools) {
            for (ExecutorService executor : threadPools.values()) {
                executor.shutdown();
            }
            threadPools.clear();
        }
    }

}

@@ -856,106 +856,468 @@
 ate.
-%0A            synchronized (threadPools) %7B%0A                final ScheduledExecutorService service =
+ So%0A            // instead of just doing the usual putIfAbsent dance, we lock the%0A            // damn thing, check to see if anyone else put a thread pool in%0A            // there while we weren't watching.%0A            synchronized (threadPools) %7B%0A                final ScheduledExecutorService lastChance = threadPools.get(name);%0A                if (lastChance == null) %7B%0A                    final ScheduledExecutorService service =%0A                           
  Exe
@@ -1395,32 +1395,36 @@
                 
+    
 threadPools.put(
@@ -1451,24 +1451,28 @@
             
+  
+  
 return servi
@@ -1475,16 +1475,98 @@
 ervice;%0A
+                %7D else %7B%0A                    return lastChance;%0A                %7D%0A
         

Fix dat race condition.