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><threadname>-javaoctave-<prefix>-<POOLNUMBER>-</code>, 51 * where <code><threadname></code> is the name of the current thread, 52 * <code><prefix></code> is the prefix given by a parameter 53 * of the constructor {@link #NamedThreadFactory(String)} 54 * and <code><POOLNUMBER></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 }