jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/api/pipe/ThreadHelper.java
changeset 35803 093fca558efd
parent 29952 6cccd9075e2f
child 36263 d5333008e409
equal deleted inserted replaced
35739:db483b34fa71 35803:093fca558efd
    26 package com.sun.xml.internal.ws.api.pipe;
    26 package com.sun.xml.internal.ws.api.pipe;
    27 
    27 
    28 import java.lang.reflect.Constructor;
    28 import java.lang.reflect.Constructor;
    29 import java.security.AccessController;
    29 import java.security.AccessController;
    30 import java.security.PrivilegedAction;
    30 import java.security.PrivilegedAction;
       
    31 import java.util.concurrent.ThreadFactory;
    31 
    32 
    32 /**
    33 /**
    33  * Simple utility class to instantiate correct Thread instance
    34  * Simple utility class to instantiate correct Thread instance
    34  * depending on runtime context (jdk/non-jdk usage)
    35  * depending on runtime context (jdk/non-jdk usage) and Java version.
    35  *
    36  *
    36  * @author miroslav.kos@oracle.com
    37  * @author miroslav.kos@oracle.com
    37  */
    38  */
    38 final class ThreadHelper {
    39 final class ThreadHelper {
    39 
    40 
    40     private static final String SAFE_THREAD_NAME = "sun.misc.ManagedLocalsThread";
    41     private static final String SAFE_THREAD_NAME = "sun.misc.ManagedLocalsThread";
    41     private static final Constructor THREAD_CONSTRUCTOR;
    42 
       
    43     private static final ThreadFactory threadFactory;
    42 
    44 
    43     // no instantiating wanted
    45     // no instantiating wanted
    44     private ThreadHelper() {
    46     private ThreadHelper() {
    45     }
    47     }
    46 
    48 
    47     static {
    49     static {
    48         THREAD_CONSTRUCTOR = AccessController.doPrivileged(
    50         threadFactory = AccessController.doPrivileged(
    49                 new PrivilegedAction<Constructor> () {
    51                 new PrivilegedAction<ThreadFactory> () {
    50                     @Override
    52                     @Override
    51                     public Constructor run() {
    53                     public ThreadFactory run() {
       
    54                         // In order of preference
    52                         try {
    55                         try {
    53                             Class cls = Class.forName(SAFE_THREAD_NAME);
    56                             try {
    54                             if (cls != null) {
    57                                 Class<Thread> cls = Thread.class;
    55                                 return cls.getConstructor(Runnable.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
    56                             }
    67                             }
       
    68                             Class<?> cls = Class.forName(SAFE_THREAD_NAME);
       
    69                             Constructor<?> ctr = cls.getConstructor(Runnable.class);
       
    70                             return new SunMiscThreadFactory(ctr);
    57                         } catch (ClassNotFoundException ignored) {
    71                         } catch (ClassNotFoundException ignored) {
    58                         } catch (NoSuchMethodException ignored) {
    72                         } catch (NoSuchMethodException ignored) {
    59                         }
    73                         }
    60                         return null;
    74                         return new LegacyThreadFactory();
    61                     }
    75                     }
    62                 }
    76                 }
    63         );
    77         );
    64     }
    78     }
    65 
    79 
    66     static Thread createNewThread(final Runnable r) {
    80     static Thread createNewThread(final Runnable r) {
    67         if (isJDKInternal()) {
    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) {
    68             return AccessController.doPrivileged(
   103             return AccessController.doPrivileged(
    69                     new PrivilegedAction<Thread>() {
   104                 new PrivilegedAction<Thread>() {
    70                         @Override
   105                     @Override
    71                         public Thread run() {
   106                     public Thread run() {
    72                             try {
   107                         try {
    73                                 return (Thread) THREAD_CONSTRUCTOR.newInstance(r);
   108                             return (Thread) ctr.newInstance(r);
    74                             } catch (Exception e) {
   109                         } catch (Exception e) {
    75                                 return new Thread(r);
   110                             return new Thread(r);
    76                             }
       
    77                         }
   111                         }
    78                     }
   112                     }
       
   113                 }
    79             );
   114             );
    80         } else {
   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) {
    81             return new Thread(r);
   121             return new Thread(r);
    82         }
   122         }
    83     }
   123     }
    84 
       
    85     private static boolean isJDKInternal() {
       
    86         String className = ThreadHelper.class.getName();
       
    87         return className.contains(".internal.");
       
    88     }
       
    89 }
   124 }