[jboss-cvs] JBossAS SVN: r91965 - in projects/jboss-threads/trunk/main/src: test/java/org/jboss/threads and 1 other directory.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Aug 4 12:04:22 EDT 2009


Author: david.lloyd at jboss.com
Date: 2009-08-04 12:04:21 -0400 (Tue, 04 Aug 2009)
New Revision: 91965

Added:
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ThreadNameInfo.java
Modified:
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThreadFactory.java
   projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ThreadFactoryTestCase.java
   projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ThreadPoolTestCase.java
Log:
Simplify thread factory impl

Modified: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThreadFactory.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThreadFactory.java	2009-08-04 14:48:41 UTC (rev 91964)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThreadFactory.java	2009-08-04 16:04:21 UTC (rev 91965)
@@ -24,8 +24,7 @@
 
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.List;
+import java.security.AccessControlContext;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicLong;
 
@@ -36,49 +35,20 @@
     private final ThreadGroup threadGroup;
     private final Boolean daemon;
     private final Integer initialPriority;
-    private final List<Appender> nameAppenderList;
     private final Thread.UncaughtExceptionHandler uncaughtExceptionHandler;
     private final Long stackSize;
+    private final String namePattern;
 
     private final AtomicLong factoryThreadIndexSequence = new AtomicLong(1L);
 
     private final long factoryIndex;
 
+    private final AccessControlContext CREATING_CONTEXT;
+
     private static final AtomicLong globalThreadIndexSequence = new AtomicLong(1L);
     private static final AtomicLong factoryIndexSequence = new AtomicLong(1L);
 
-    private static final Appender globalThreadIndexAppender = new Appender() {
-        public void appendTo(final StringBuilder target, final ThreadSequenceInfo info) {
-            target.append(info.getGlobalThreadNum());
-        }
-    };
-    private static final Appender factoryIndexAppender = new Appender() {
-        public void appendTo(final StringBuilder target, final ThreadSequenceInfo info) {
-            target.append(info.getFactoryNum());
-        }
-    };
-    private static final Appender perFactoryThreadIndexAppender = new Appender() {
-        public void appendTo(final StringBuilder target, final ThreadSequenceInfo info) {
-            target.append(info.getPerFactoryThreadNum());
-        }
-    };
-    private static final Appender percentAppender = new Appender() {
-        public void appendTo(final StringBuilder target, final ThreadSequenceInfo info) {
-            target.append('%');
-        }
-    };
-    private final Appender groupPathAppender;
-
-    private static void appendParent(ThreadGroup group, StringBuilder builder) {
-        final ThreadGroup parent = group.getParent();
-        if (parent != null) {
-            appendParent(parent, builder);
-            builder.append(':');
-        }
-        builder.append(group.getName());
-    }
-
-    public JBossThreadFactory(ThreadGroup threadGroup, final Boolean daemon, final Integer initialPriority, String namePattern, final InterruptHandler[] interruptHandlers, final Thread.UncaughtExceptionHandler uncaughtExceptionHandler, final Long stackSize) {
+    public JBossThreadFactory(ThreadGroup threadGroup, final Boolean daemon, final Integer initialPriority, String namePattern, final Thread.UncaughtExceptionHandler uncaughtExceptionHandler, final Long stackSize) {
         if (threadGroup == null) {
             final SecurityManager sm = System.getSecurityManager();
             threadGroup = sm != null ? sm.getThreadGroup() : Thread.currentThread().getThreadGroup();
@@ -88,61 +58,20 @@
         this.initialPriority = initialPriority;
         this.uncaughtExceptionHandler = uncaughtExceptionHandler;
         this.stackSize = stackSize;
-        final StringBuilder builder = new StringBuilder();
-        appendParent(threadGroup, builder);
-        final String groupPath = builder.toString();
-        groupPathAppender = new StringAppender(groupPath);
-
         factoryIndex = factoryIndexSequence.getAndIncrement();
         if (namePattern == null) {
             namePattern = "pool-%f-thread-%t";
         }
-        List<Appender> appenders = new ArrayList<Appender>();
-        final int len = namePattern.length();
-        for (int i = 0;; ) {
-            final int n = namePattern.indexOf('%', i);
-            if (n == -1) {
-                if (i < len) {
-                    appenders.add(new StringAppender(namePattern.substring(i)));
-                }
-                break;
-            }
-            if (n > i) {
-                appenders.add(new StringAppender(namePattern.substring(i, n)));
-            }
-            if (n >= len - 1) {
-                break;
-            }
-            final char c = namePattern.charAt(n + 1);
-            switch (c) {
-                case 't': {
-                    appenders.add(perFactoryThreadIndexAppender);
-                    break;
-                }
-                case 'g': {
-                    appenders.add(globalThreadIndexAppender);
-                    break;
-                }
-                case 'f': {
-                    appenders.add(factoryIndexAppender);
-                    break;
-                }
-                case 'p': {
-                    appenders.add(groupPathAppender);
-                    break;
-                }
-                case '%': {
-                    appenders.add(percentAppender);
-                    break;
-                }
-            }
-            i = n + 2;
-        }
-        nameAppenderList = appenders;
+        this.namePattern = namePattern;
+        CREATING_CONTEXT = AccessController.getContext();
     }
 
     public Thread newThread(final Runnable target) {
-        return AccessController.doPrivileged(new ThreadCreateAction(target));
+        if (System.getSecurityManager() != null) {
+            return AccessController.doPrivileged(new ThreadCreateAction(target), CREATING_CONTEXT);
+        } else {
+            return createThread(target);
+        }
     }
 
     private final class ThreadCreateAction implements PrivilegedAction<Thread> {
@@ -153,61 +82,22 @@
         }
 
         public Thread run() {
-            final JBossThread thread;
-            final ThreadSequenceInfo info = new ThreadSequenceInfo(globalThreadIndexSequence.getAndIncrement(), factoryThreadIndexSequence.getAndIncrement(), factoryIndex);
-            final StringBuilder nameBuilder = new StringBuilder();
-            for (Appender appender : nameAppenderList) {
-                appender.appendTo(nameBuilder, info);
-            }
-            if (stackSize != null) {
-                thread = new JBossThread(threadGroup, target, nameBuilder.toString(), stackSize.longValue());
-            } else {
-                thread = new JBossThread(threadGroup, target, nameBuilder.toString());
-            }
-            if (initialPriority != null) thread.setPriority(initialPriority.intValue());
-            if (daemon != null) thread.setDaemon(daemon.booleanValue());
-            if (uncaughtExceptionHandler != null) thread.setUncaughtExceptionHandler(uncaughtExceptionHandler);
-            return thread;
+            return createThread(target);
         }
     }
 
-    private static final class StringAppender implements Appender {
-        private final String string;
-
-        private StringAppender(final String string) {
-            this.string = string;
+    private Thread createThread(final Runnable target) {
+        final ThreadNameInfo nameInfo = new ThreadNameInfo(globalThreadIndexSequence.getAndIncrement(), factoryThreadIndexSequence.getAndIncrement(), factoryIndex);
+        final JBossThread thread;
+        if (stackSize != null) {
+            thread = new JBossThread(threadGroup, target, "<new>", stackSize.longValue());
+        } else {
+            thread = new JBossThread(threadGroup, target);
         }
-
-        public void appendTo(final StringBuilder target, final ThreadSequenceInfo info) {
-            target.append(string);
-        }
+        thread.setName(nameInfo.format(thread, namePattern));
+        if (initialPriority != null) thread.setPriority(initialPriority.intValue());
+        if (daemon != null) thread.setDaemon(daemon.booleanValue());
+        if (uncaughtExceptionHandler != null) thread.setUncaughtExceptionHandler(uncaughtExceptionHandler);
+        return thread;
     }
-
-    private static final class ThreadSequenceInfo {
-        private final long globalThreadNum;
-        private final long perFactoryThreadNum;
-        private final long factoryNum;
-
-        private ThreadSequenceInfo(final long globalThreadNum, final long perFactoryThreadNum, final long factoryNum) {
-            this.globalThreadNum = globalThreadNum;
-            this.perFactoryThreadNum = perFactoryThreadNum;
-            this.factoryNum = factoryNum;
-        }
-
-        public long getGlobalThreadNum() {
-            return globalThreadNum;
-        }
-
-        public long getPerFactoryThreadNum() {
-            return perFactoryThreadNum;
-        }
-
-        public long getFactoryNum() {
-            return factoryNum;
-        }
-    }
-
-    private interface Appender {
-        void appendTo(StringBuilder target, ThreadSequenceInfo info);
-    }
 }

Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ThreadNameInfo.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ThreadNameInfo.java	                        (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ThreadNameInfo.java	2009-08-04 16:04:21 UTC (rev 91965)
@@ -0,0 +1,102 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+/**
+ * Thread name information.
+ */
+final class ThreadNameInfo {
+    private final long globalThreadSequenceNum;
+    private final long perFactoryThreadSequenceNum;
+    private final long factorySequenceNum;
+
+    ThreadNameInfo(final long globalThreadSequenceNum, final long perFactoryThreadSequenceNum, final long factorySequenceNum) {
+        this.globalThreadSequenceNum = globalThreadSequenceNum;
+        this.perFactoryThreadSequenceNum = perFactoryThreadSequenceNum;
+        this.factorySequenceNum = factorySequenceNum;
+    }
+
+    public long getGlobalThreadSequenceNum() {
+        return globalThreadSequenceNum;
+    }
+
+    public long getPerFactoryThreadSequenceNum() {
+        return perFactoryThreadSequenceNum;
+    }
+
+    public long getFactorySequenceNum() {
+        return factorySequenceNum;
+    }
+
+    private static final Pattern searchPattern = Pattern.compile("([^%]+)|%.");
+
+    /**
+     * Format the thread name string.
+     * <ul>
+     * <li>{@code %%} - emit a percent sign</li>
+     * <li>{@code %t} - emit the per-factory thread sequence number</li>
+     * <li>{@code %g} - emit the global thread sequence number</li>
+     * <li>{@code %f} - emit the factory sequence number</li>
+     * <li>{@code %p} - emit the {@code ":"}-separated thread group path</li>
+     * <li>{@code %i} - emit the thread ID</li>
+     * <li>{@code %G} - emit the thread group name</li>
+     * </ul>
+     *
+     * @param thread the thread
+     * @param formatString the format string
+     * @return the thread name string
+     */
+    public String format(Thread thread, String formatString) {
+        final StringBuilder builder = new StringBuilder(formatString.length() * 5);
+        final ThreadGroup group = thread.getThreadGroup();
+        final Matcher matcher = searchPattern.matcher(formatString);
+        while (matcher.find()) {
+            if (matcher.group(1) != null) {
+                builder.append(matcher.group());
+            } else {
+                switch (matcher.group().charAt(1)) {
+                    case '%': builder.append('%'); break;
+                    case 't': builder.append(perFactoryThreadSequenceNum); break;
+                    case 'g': builder.append(globalThreadSequenceNum); break;
+                    case 'f': builder.append(factorySequenceNum); break;
+                    case 'p': if (group != null) appendGroupPath(group, builder); break;
+                    case 'i': builder.append(thread.getId());
+                    case 'G': if (group != null) builder.append(group.getName()); break;
+                }
+            }
+        }
+        return builder.toString();
+    }
+
+    private static void appendGroupPath(ThreadGroup group, StringBuilder builder) {
+        final ThreadGroup parent = group.getParent();
+        if (parent != null) {
+            appendGroupPath(parent, builder);
+            builder.append(':');
+        }
+        builder.append(group.getName());
+    }
+}

Modified: projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ThreadFactoryTestCase.java
===================================================================
--- projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ThreadFactoryTestCase.java	2009-08-04 14:48:41 UTC (rev 91964)
+++ projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ThreadFactoryTestCase.java	2009-08-04 16:04:21 UTC (rev 91965)
@@ -49,12 +49,12 @@
         // TODO - skip test for now since it depends on order.
         if (true) return;
         final JBossThreadFactory threadFactory1 = new JBossThreadFactory(new ThreadGroup(new ThreadGroup(new ThreadGroup("one"), "two"), "three"), null,
-                null, "-%p-%%-%t-%g-%f-", null, null, null);
+                null, "-%p-%%-%t-%g-%f-", null, null);
         doTestNamePattern(threadFactory1, 1, 1, 1);
         doTestNamePattern(threadFactory1, 2, 2, 1);
         doTestNamePattern(threadFactory1, 3, 3, 1);
         final JBossThreadFactory threadFactory2 = new JBossThreadFactory(new ThreadGroup(new ThreadGroup(new ThreadGroup("one"), "two"), "three"), null,
-                null, "-%p-%%-%t-%g-%f-", null, null, null);
+                null, "-%p-%%-%t-%g-%f-", null, null);
         doTestNamePattern(threadFactory2, 1, 4, 2);
         doTestNamePattern(threadFactory2, 2, 5, 2);
         doTestNamePattern(threadFactory2, 3, 6, 2);
@@ -64,22 +64,16 @@
     }
 
     public void testDaemon() {
-        final JBossThreadFactory threadFactory1 = new JBossThreadFactory(null, Boolean.TRUE, null, "%t", null, null, null);
+        final JBossThreadFactory threadFactory1 = new JBossThreadFactory(null, Boolean.TRUE, null, "%t", null, null);
         assertTrue("Thread is not a daemon thread", threadFactory1.newThread(NULL_RUNNABLE).isDaemon());
-        final JBossThreadFactory threadFactory2 = new JBossThreadFactory(null, Boolean.FALSE, null, "%t", null, null, null);
+        final JBossThreadFactory threadFactory2 = new JBossThreadFactory(null, Boolean.FALSE, null, "%t", null, null);
         assertFalse("Thread should not be a daemon thread", threadFactory2.newThread(NULL_RUNNABLE).isDaemon());
     }
 
     public void testInterruptHandler() throws InterruptedException {
         final AtomicBoolean wasInterrupted = new AtomicBoolean();
         final AtomicBoolean called = new AtomicBoolean();
-        final JBossThreadFactory threadFactory = new JBossThreadFactory(null, null, null, null, new InterruptHandler[] {
-                new InterruptHandler() {
-                    public void handleInterrupt(final Thread thread) {
-                        called.set(true);
-                    }
-                }
-        }, null, null);
+        final JBossThreadFactory threadFactory = new JBossThreadFactory(null, null, null, null, null, null);
         final Thread t = threadFactory.newThread(new Runnable() {
             public void run() {
                 synchronized (this) {
@@ -100,7 +94,7 @@
 
     public void testUncaughtHandler() throws InterruptedException {
         final AtomicBoolean called = new AtomicBoolean();
-        final JBossThreadFactory factory = new JBossThreadFactory(null, null, null, null, null, new Thread.UncaughtExceptionHandler() {
+        final JBossThreadFactory factory = new JBossThreadFactory(null, null, null, null, new Thread.UncaughtExceptionHandler() {
             public void uncaughtException(final Thread t, final Throwable e) {
                 called.set(true);
             }
@@ -116,11 +110,11 @@
     }
 
     public void testInitialPriority() {
-        assertEquals("Wrong initial thread priority", 1, new JBossThreadFactory(null, null, Integer.valueOf(1), null, null, null, null).newThread(NULL_RUNNABLE).getPriority());
-        assertEquals("Wrong initial thread priority", 2, new JBossThreadFactory(null, null, Integer.valueOf(2), null, null, null, null).newThread(NULL_RUNNABLE).getPriority());
+        assertEquals("Wrong initial thread priority", 1, new JBossThreadFactory(null, null, Integer.valueOf(1), null, null, null).newThread(NULL_RUNNABLE).getPriority());
+        assertEquals("Wrong initial thread priority", 2, new JBossThreadFactory(null, null, Integer.valueOf(2), null, null, null).newThread(NULL_RUNNABLE).getPriority());
         final ThreadGroup grp = new ThreadGroup("blah");
         grp.setMaxPriority(5);
-        assertEquals("Wrong initial thread priority", 5, new JBossThreadFactory(grp, null, Integer.valueOf(10), null, null, null, null).newThread(NULL_RUNNABLE).getPriority());
-        assertEquals("Wrong initial thread priority", 1, new JBossThreadFactory(grp, null, Integer.valueOf(1), null, null, null, null).newThread(NULL_RUNNABLE).getPriority());
+        assertEquals("Wrong initial thread priority", 5, new JBossThreadFactory(grp, null, Integer.valueOf(10), null, null, null).newThread(NULL_RUNNABLE).getPriority());
+        assertEquals("Wrong initial thread priority", 1, new JBossThreadFactory(grp, null, Integer.valueOf(1), null, null, null).newThread(NULL_RUNNABLE).getPriority());
     }
 }

Modified: projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ThreadPoolTestCase.java
===================================================================
--- projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ThreadPoolTestCase.java	2009-08-04 14:48:41 UTC (rev 91964)
+++ projects/jboss-threads/trunk/main/src/test/java/org/jboss/threads/ThreadPoolTestCase.java	2009-08-04 16:04:21 UTC (rev 91965)
@@ -35,7 +35,7 @@
  */
 public final class ThreadPoolTestCase extends TestCase {
 
-    private final JBossThreadFactory threadFactory = new JBossThreadFactory(null, null, null, "test thread %p %t", null, null, null);
+    private final JBossThreadFactory threadFactory = new JBossThreadFactory(null, null, null, "test thread %p %t", null, null);
 
     private static final class SimpleTask implements Runnable {
 




More information about the jboss-cvs-commits mailing list