public static LoggingThreadGroup createThreadGroup(final String name, final Logger logger) {
    // Cache the LoggingThreadGroups so that we don't create a
    // gazillion of them.
    LoggingThreadGroup group = null;
    synchronized (loggingThreadGroups) {
      for (Iterator<LoggingThreadGroup> iter = loggingThreadGroups.iterator(); iter.hasNext();) {

        LoggingThreadGroup group2 = iter.next();
        if (group2.isDestroyed()) {
          // Clean is this iterator out
          iter.remove();
          continue;
        }

        if (name.equals(group2.getName())) {
          // We already have one!
          // Change the underlying logger to point to new one (creating new
          // thread groups for different loggers leaks groups for repeated
          // connect/disconnects as in dunits for example)
          if (logger != group2.logger) {
            group2.logger = logger;
          }
          group = group2;
          break;
        }
      }

      if (group == null) {
        group = new LoggingThreadGroup(name, logger);
        // force autoclean to false and not inherit from parent group
        group.setDaemon(false);
        loggingThreadGroups.add(group);
      }
    }

    Assert.assertTrue(!group.isDestroyed());
    return group;
  }
Returns a <code>ThreadGroup</code> whose {@link ThreadGroup#uncaughtException} method logs to
both {#link System#err} and the given <code>InternalLogWriter</code>.

@param name The name of the <code>ThreadGroup</code>
@param logger A <code>InternalLogWriter</code> to log uncaught exceptions to. It is okay for
       this argument to be <code>null</code>.

@since GemFire 3.0
geode-core/src/main/java/org/apache/geode/internal/logging/LoggingThreadGroup.java