1 /* 2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.xml.internal.ws.api.pipe; 27 28 import java.lang.reflect.Constructor; 29 import java.security.AccessController; 30 import java.security.PrivilegedAction; 31 import java.util.concurrent.ThreadFactory; 32 33 /** 34 * Simple utility class to instantiate correct Thread instance 35 * depending on Java version. 36 * 37 * @author miroslav.kos@oracle.com 38 */ 39 final class ThreadHelper { 40 41 private static final String SAFE_THREAD_NAME = "sun.misc.ManagedLocalsThread"; 42 43 private static final ThreadFactory threadFactory; 44 45 // no instantiating wanted 46 private ThreadHelper() { 47 } 48 49 static { 50 threadFactory = AccessController.doPrivileged( 51 new PrivilegedAction<ThreadFactory> () { 52 @Override 53 public ThreadFactory run() { 54 // In order of preference 55 try { 56 try { 57 Class<Thread> cls = Thread.class; 58 Constructor<Thread> ctr = cls.getConstructor( 59 ThreadGroup.class, 60 Runnable.class, 61 String.class, 62 long.class, 63 boolean.class); 64 return new JDK9ThreadFactory(ctr); 65 } catch (NoSuchMethodException ignored) { 66 // constructor newly added in Java SE 9 67 } 68 Class<?> cls = Class.forName(SAFE_THREAD_NAME); 69 Constructor<?> ctr = cls.getConstructor(Runnable.class); 70 return new SunMiscThreadFactory(ctr); 71 } catch (ClassNotFoundException ignored) { 72 } catch (NoSuchMethodException ignored) { 73 } 74 return new LegacyThreadFactory(); 75 } 76 } 77 ); 78 } 79 80 static Thread createNewThread(final Runnable r) { 81 return threadFactory.newThread(r); 82 } 83 84 // A Thread factory backed by the Thread constructor that 85 // suppresses inheriting of inheritable thread-locals. 86 private static class JDK9ThreadFactory implements ThreadFactory { 87 final Constructor<Thread> ctr; 88 JDK9ThreadFactory(Constructor<Thread> ctr) { this.ctr = ctr; } 89 @Override public Thread newThread(Runnable r) { 90 try { 91 return ctr.newInstance(null, r, "toBeReplaced", 0, false); 92 } catch (ReflectiveOperationException x) { 93 throw new InternalError(x); 94 } 95 } 96 } 97 98 // A Thread factory backed by sun.misc.ManagedLocalsThread 99 private static class SunMiscThreadFactory implements ThreadFactory { 100 final Constructor<?> ctr; 101 SunMiscThreadFactory(Constructor<?> ctr) { this.ctr = ctr; } 102 @Override public Thread newThread(Runnable r) { 103 return AccessController.doPrivileged( 104 new PrivilegedAction<Thread>() { 105 @Override 106 public Thread run() { 107 try { 108 return (Thread) ctr.newInstance(r); 109 } catch (Exception e) { 110 return new Thread(r); 111 } 112 } 113 } 114 ); 115 } 116 } 117 118 // A Thread factory backed by new Thread(Runnable) 119 private static class LegacyThreadFactory implements ThreadFactory { 120 @Override public Thread newThread(Runnable r) { 121 return new Thread(r); 122 } 123 } 124 }