[jboss-cvs] JBossAS SVN: r91883 - projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Jul 31 12:47:13 EDT 2009


Author: david.lloyd at jboss.com
Date: 2009-07-31 12:47:13 -0400 (Fri, 31 Jul 2009)
New Revision: 91883

Modified:
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DirectExecutor.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThread.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThreadFactory.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutor.java
Log:
Create a better interrupt handler system

Modified: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DirectExecutor.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DirectExecutor.java	2009-07-31 16:21:59 UTC (rev 91882)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DirectExecutor.java	2009-07-31 16:47:13 UTC (rev 91883)
@@ -25,7 +25,7 @@
 import java.util.concurrent.Executor;
 
 /**
- * A direct executor.  Such an executor is required to run the given task in the current thread rather than
+ * A direct executor.  Such an executor is <b>required</b> to run the given task in the current thread rather than
  * delegate to a thread pool.
  *
  * @see JBossExecutors#directExecutor()
@@ -35,7 +35,8 @@
  * @see JBossExecutors#contextClassLoaderExecutor(org.jboss.threads.DirectExecutor, java.lang.ClassLoader)
  * @see JBossExecutors#threadNameExecutor(org.jboss.threads.DirectExecutor, java.lang.String)
  * @see JBossExecutors#threadNameNotateExecutor(org.jboss.threads.DirectExecutor, java.lang.String)
- * @see JBossExecutors#exceptionLoggingExecutor(org.jboss.threads.DirectExecutor, java.lang.Object)
+ * @see JBossExecutors#exceptionLoggingExecutor(DirectExecutor, org.jboss.logging.Logger)
+ * @see JBossExecutors#exceptionLoggingExecutor(DirectExecutor)
  * @see JBossExecutors#resettingExecutor(org.jboss.threads.DirectExecutor)
  */
 public interface DirectExecutor extends Executor {

Modified: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThread.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThread.java	2009-07-31 16:21:59 UTC (rev 91882)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThread.java	2009-07-31 16:47:13 UTC (rev 91883)
@@ -25,29 +25,44 @@
 import org.jboss.logging.Logger;
 
 /**
- *
+ * A JBoss thread.  Supports extra logging and operations.
  */
 public final class JBossThread extends Thread {
     private static final Logger log = Logger.getLogger(JBossThread.class);
 
-    private final InterruptHandler[] interruptHandlers;
+    private InterruptHandler interruptHandler;
 
-    public JBossThread(final InterruptHandler[] handlers, final ThreadGroup group, final Runnable target, final String name, final long stackSize) {
-        super(group, target, name, stackSize);
-        interruptHandlers = handlers;
+    public JBossThread(final Runnable target) {
+        super(target);
     }
 
-    public JBossThread(final InterruptHandler[] handlers, final ThreadGroup group, final Runnable target, final String name) {
+    public JBossThread(final Runnable target, final String name) {
+        super(target, name);
+    }
+
+    public JBossThread(final ThreadGroup group, final Runnable target) {
+        super(group, target);
+    }
+
+    public JBossThread(final ThreadGroup group, final Runnable target, final String name) {
         super(group, target, name);
-        interruptHandlers = handlers;
     }
 
+    public JBossThread(final ThreadGroup group, final Runnable target, final String name, final long stackSize) {
+        super(group, target, name, stackSize);
+    }
+
+    /**
+     * Interrupt this thread.  Logs a trace message and calls the current interrupt handler, if any.  The interrupt
+     * handler is called from the <em>calling</em> thread, not the thread being interrupted.
+     */
     public void interrupt() {
+        log.tracef("Interrupting thread \"%s\"", this);
         try {
             super.interrupt();
         } finally {
-            if (interruptHandlers != null) {
-                for (InterruptHandler interruptHandler : interruptHandlers) try {
+            if (interruptHandler != null) {
+                try {
                     interruptHandler.handleInterrupt(this);
                 } catch (Throwable t) {
                     log.errorf(t, "Interrupt handler %s threw an exception", interruptHandler);
@@ -56,12 +71,72 @@
         }
     }
 
+    /**
+     * Execute the thread's {@code Runnable}.  Logs a trace message at the start and end of execution.
+     */
     public void run() {
-        log.tracef("Starting thread %s", this);
+        log.tracef("Thread \"%s\" starting execution", this);
         try {
             super.run();
         } finally {
-            log.tracef("Terminating thread %s", this);
+            log.tracef("Thread \"%s\" exiting", this);
         }
     }
+
+    /**
+     * Get the current {@code JBossThread}, or {@code null} if the current thread is not a {@code JBossThread}.
+     *
+     * @return the current thread, or {@code null}
+     */
+    public static JBossThread currentThread() {
+        final Thread thread = Thread.currentThread();
+        return thread instanceof JBossThread ? (JBossThread) thread : null;
+    }
+
+    /**
+     * Start the thread.
+     *
+     * @throws IllegalThreadStateException if the thread was already started.
+     */
+    public void start() {
+        super.start();
+        log.tracef("Started thread \"%s\"", this);
+    }
+
+    /**
+     * Change the uncaught exception handler for this thread.
+     *
+     * @param eh the new handler
+     */
+    public void setUncaughtExceptionHandler(final UncaughtExceptionHandler eh) {
+        super.setUncaughtExceptionHandler(eh);
+        log.tracef("Changed uncaught exception handler for \"%s\" to %s", this, eh);
+    }
+
+    /**
+     * Swap the current thread's active interrupt handler.  Most callers should restore the old handler in a {@code finally}
+     * block like this:
+     * <pre>
+     * InterruptHandler oldHandler = JBossThread.getAndSetInterruptHandler(newHandler);
+     * try {
+     *     ...execute interrupt-sensitive operation...
+     * } finally {
+     *     JBossThread.getAndSetInterruptHandler(oldHandler);
+     * }
+     * </pre>
+     *
+     * @param newInterruptHandler the new interrupt handler
+     * @return the old interrupt handler
+     */
+    public static InterruptHandler getAndSetInterruptHandler(final InterruptHandler newInterruptHandler) {
+        final JBossThread thread = currentThread();
+        if (thread == null) {
+            throw new IllegalStateException("The current thread does not support interrupt handlers");
+        }
+        try {
+            return thread.interruptHandler;
+        } finally {
+            thread.interruptHandler = newInterruptHandler;
+        }
+    }
 }

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-07-31 16:21:59 UTC (rev 91882)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossThreadFactory.java	2009-07-31 16:47:13 UTC (rev 91883)
@@ -37,7 +37,6 @@
     private final Boolean daemon;
     private final Integer initialPriority;
     private final List<Appender> nameAppenderList;
-    private final InterruptHandler[] interruptHandlers;
     private final Thread.UncaughtExceptionHandler uncaughtExceptionHandler;
     private final Long stackSize;
 
@@ -88,7 +87,6 @@
         this.daemon = daemon;
         this.initialPriority = initialPriority;
         this.uncaughtExceptionHandler = uncaughtExceptionHandler;
-        this.interruptHandlers = interruptHandlers;
         this.stackSize = stackSize;
         final StringBuilder builder = new StringBuilder();
         appendParent(threadGroup, builder);
@@ -162,9 +160,9 @@
                 appender.appendTo(nameBuilder, info);
             }
             if (stackSize != null) {
-                thread = new JBossThread(interruptHandlers, threadGroup, target, nameBuilder.toString(), stackSize.longValue());
+                thread = new JBossThread(threadGroup, target, nameBuilder.toString(), stackSize.longValue());
             } else {
-                thread = new JBossThread(interruptHandlers, threadGroup, target, nameBuilder.toString());
+                thread = new JBossThread(threadGroup, target, nameBuilder.toString());
             }
             if (initialPriority != null) thread.setPriority(initialPriority.intValue());
             if (daemon != null) thread.setDaemon(daemon.booleanValue());

Modified: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutor.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutor.java	2009-07-31 16:21:59 UTC (rev 91882)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutor.java	2009-07-31 16:47:13 UTC (rev 91883)
@@ -43,4 +43,8 @@
     public void execute(final Runnable command) {
         delegate.execute(command);
     }
+
+    public String toString() {
+        return String.format("%s -> %s", super.toString(), delegate);
+    }
 }




More information about the jboss-cvs-commits mailing list