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 */
38 private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1);
39
40 /**
41 * The thread group either from the security manager
42 * or from the current thread.
43 */
44 private final ThreadGroup group;
45
46 /**
47 * The name prefix of the form
48 * <code><threadname>-javaoctave-<prefix>-<POOLNUMBER>-</code>,
49 * where <code><threadname></code> is the name of the current thread,
50 * <code><prefix></code> is the prefix given by a parameter
51 * of the constructor {@link #NamedThreadFactory(String)}
52 * and <code><POOLNUMBER></code> is {@link #POOL_NUMBER}
53 * depending on the factory object.
54 * The trailing <code>-</code> is there because a new thread
55 * defined by {@link #newThread(Runnable)} obtains a name
56 * consisting of the prefix followed by {@link #threadNumber}.
57 */
58 private final String namePrefix;
59
60 /**
61 * The number of the thread created next by this factory starting with one
62 * and being incremented by method {@link #newThread(Runnable)}.
63 *
64 */
65 private final AtomicInteger threadNumber = new AtomicInteger(1);
66
67 /**
68 * Will create a factory that create Threads with the names:
69 * <code>[parent]-javaoctave-[prefix]-[pool#]-[thread#]</code>.
70 * Here, <code>[parent]</code> is the name of the parent thread,
71 * i.e. of the current thread,
72 * <code>[prefix]</code> is given by the parameter
73 * <code>[pool#]</code> is the number of this factory
74 * and <code>[thread#]</code> refers to the number of the thread
75 * created by this factory.
76 *
77 * @param prefix
78 */
79 @SuppressWarnings("PMD.AvoidThreadGroup")
80 // Thread.getThreadGroup() causes warning
81 // only because threadgroup has methods which are not threadsafe.
82 // but we do not invoke method on group,
83 // use just to create new thread with that group.
84 private NamedThreadFactory(final String prefix) {
85 final SecurityManager securityManager = System.getSecurityManager();
86 this.group = (securityManager == null)
87 ? Thread.currentThread().getThreadGroup()
88 : securityManager .getThreadGroup();
89 this.namePrefix = Thread.currentThread().getName() + "-javaoctave-"
90 + prefix + "-" + POOL_NUMBER.getAndIncrement() + "-";
91 }
92
93 public NamedThreadFactory() {
94 this(OctaveExec.class.getSimpleName());
95 }
96
97 /**
98 * Returns a new thread with standard priority which is no daemon
99 * from <code>runnable</code>
100 * with name consisting of {@link #namePrefix} and a running number
101 * {@link #threadNumber}.
102 *
103 * @param runnable
104 * the runnable to create a thread from.
105 */
106 @Override
107 public Thread newThread(final Runnable runnable) {
108 String name = this.namePrefix + this.threadNumber.getAndIncrement();
109 final Thread thread = new Thread(this.group, runnable, name);
110 if (thread.isDaemon()) {
111 thread.setDaemon(false);
112 }
113 // Here, thread is no daemon
114 if (thread.getPriority() != Thread.NORM_PRIORITY) {
115 thread.setPriority(Thread.NORM_PRIORITY);
116 }
117 // Here, thread has NORM_PRIORITY
118 return thread;
119 }
120
121 }