View Javadoc
1   /*
2    * Copyright 2008 Ange Optimization ApS
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreeds to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  /**
17   * @author Kim Hansen
18   */
19  package eu.simuline.octave.util;
20  
21  import eu.simuline.octave.exec.OctaveExec;
22  
23  import java.util.concurrent.ThreadFactory;
24  import java.util.concurrent.atomic.AtomicInteger;
25  
26  /**
27   * A ThreadFactory that allows to create a thread from a runnable 
28   * with a specific thread name. 
29   * 
30   * @author Kim Hansen
31   */
32  public final class NamedThreadFactory implements ThreadFactory {
33  
34      /**
35       * This is initialized with 1 
36       * and read and incremented only if a factory object is created. 
37       * It goes into {@link #namePrefix}. 
38       */
39      private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1);
40  
41      /**
42       * The thread group from the security manager if it exists 
43       * or else from the current thread. 
44       * It is the group each thread belongs to created by {@link #newThread(Runnable)}. 
45       */
46      private final ThreadGroup group;
47  
48      /**
49       * The name prefix of the form 
50       * <code>&lt;threadname&gt;-javaoctave-&lt;prefix&gt;-&lt;POOLNUMBER&gt;-</code>, 
51       * where <code>&lt;threadname&gt;</code> is the name of the current thread, 
52       * <code>&lt;prefix&gt;</code> is the prefix given by a parameter 
53       * of the constructor {@link #NamedThreadFactory(String)} 
54       * and <code>&lt;POOLNUMBER&gt;</code> is {@link #POOL_NUMBER} 
55       * depending on the factory object. 
56       * The trailing <code>-</code> is there because a new thread 
57       * defined by {@link #newThread(Runnable)} obtains a name 
58       * consisting of the prefix followed by {@link #threadNumber}. 
59       */
60      private final String namePrefix;
61  
62      /**
63       * The number of the thread created next by this factory starting with one 
64       * and being incremented by method {@link #newThread(Runnable)}. 
65       * 
66       */
67      private final AtomicInteger threadNumber = new AtomicInteger(1);
68  
69      /**
70       * Will create a factory that create Threads with the names: 
71       * <code>[parent]-javaoctave-[prefix]-[pool#]-[thread#]</code>. 
72       * Here, <code>[parent]</code> is the name of the parent thread, 
73       * i.e. of the current thread, 
74       * <code>[prefix]</code> is given by the parameter 
75       * <code>[pool#]</code> is the number of this factory 
76       * and <code>[thread#]</code> refers to the number of the thread 
77       * created by this factory. 
78       * 
79       * @param prefix
80       */
81      @SuppressWarnings("PMD.AvoidThreadGroup")
82      // Thread.getThreadGroup() causes warning 
83      // only because threadgroup has methods which are not threadsafe. 
84      // but we do not invoke method on group, 
85      // use just to create new thread with that group. 
86      private NamedThreadFactory(final String prefix) {
87          final SecurityManager securityManager = System.getSecurityManager();
88          this.group = (securityManager == null) 
89  	    ? Thread.currentThread().getThreadGroup()
90  	    : securityManager       .getThreadGroup();
91          this.namePrefix = Thread.currentThread().getName() + "-javaoctave-" 
92  	    + prefix + "-" + POOL_NUMBER.getAndIncrement() + "-";
93      }
94  
95      /**
96       * Creates a NamedThreadFactory via {@link #NamedThreadFactory(String)} 
97       * with name given by the simple class name of {@link OctaveExec}. 
98       */
99      public NamedThreadFactory() {
100 	this(OctaveExec.class.getSimpleName());
101     }
102 
103     /**
104      * Returns a new thread with standard priority which is no daemon 
105      * with default priority {@link Thread#NORM_PRIORITY} 
106      * from <code>runnable</code> 
107      * with name consisting of {@link #namePrefix} and a running number 
108      * {@link #threadNumber}. 
109      *
110      * @param runnable
111      *    the runnable to create a thread from. 
112      */
113     @Override
114     public Thread newThread(final Runnable runnable) {
115 	String name = this.namePrefix + this.threadNumber.getAndIncrement();
116         final Thread thread = new Thread(this.group, runnable, name);
117         if (thread.isDaemon()) {
118             // is a daemon iff this thread is a daemon 
119             thread.setDaemon(false);
120         }
121 	// Here, thread is no daemon 
122         if (thread.getPriority() != Thread.NORM_PRIORITY) {
123             thread.setPriority(Thread.NORM_PRIORITY);
124         }
125 	// Here, thread has NORM_PRIORITY 
126         return thread;
127     }
128 
129 }