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 } |