13
13
*/
14
14
package ch .qos .logback .core .util ;
15
15
16
+ import java .lang .reflect .InvocationTargetException ;
17
+ import java .lang .reflect .Method ;
16
18
import java .util .concurrent .ExecutorService ;
17
19
import java .util .concurrent .Executors ;
18
20
import java .util .concurrent .ScheduledExecutorService ;
33
35
*/
34
36
public class ExecutorServiceUtil {
35
37
36
- private static final ThreadFactory THREAD_FACTORY = new ThreadFactory () {
38
+ static private final String NEW_VIRTUAL_TPT_METHOD_NAME = "newVirtualThreadPerTaskExecutor" ;
39
+
40
+ private static final ThreadFactory THREAD_FACTORY_FOR_SCHEDULED_EXECUTION_SERVICE = new ThreadFactory () {
37
41
38
- private final ThreadFactory defaultFactory = Executors .defaultThreadFactory ();
39
42
private final AtomicInteger threadNumber = new AtomicInteger (1 );
40
43
44
+
45
+ private final ThreadFactory defaultFactory = makeThreadFactory ();
46
+
47
+ /**
48
+ * A thread factory which may be a virtual thread factory if available.
49
+ *
50
+ * @return
51
+ */
52
+ private ThreadFactory makeThreadFactory () {
53
+ if (EnvUtil .isJDK21OrHigher ()) {
54
+ try {
55
+ Method ofVirtualMethod = Thread .class .getMethod ("ofVirtual" );
56
+ Object threadBuilderOfVirtual = ofVirtualMethod .invoke (null );
57
+ Method factoryMethod = threadBuilderOfVirtual .getClass ().getMethod ("factory" );
58
+ System .out .println ("virtual THREAD FACTORY" );
59
+ return (ThreadFactory ) factoryMethod .invoke (threadBuilderOfVirtual );
60
+ } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e ) {
61
+ return Executors .defaultThreadFactory ();
62
+ }
63
+
64
+ } else {
65
+ System .out .println ("default THREAD FACTORY" );
66
+ return Executors .defaultThreadFactory ();
67
+ }
68
+ }
69
+
70
+ @ Override
41
71
public Thread newThread (Runnable r ) {
42
72
Thread thread = defaultFactory .newThread (r );
43
73
if (!thread .isDaemon ()) {
@@ -49,7 +79,8 @@ public Thread newThread(Runnable r) {
49
79
};
50
80
51
81
static public ScheduledExecutorService newScheduledExecutorService () {
52
- return new ScheduledThreadPoolExecutor (CoreConstants .SCHEDULED_EXECUTOR_POOL_SIZE , THREAD_FACTORY );
82
+ return new ScheduledThreadPoolExecutor (CoreConstants .SCHEDULED_EXECUTOR_POOL_SIZE ,
83
+ THREAD_FACTORY_FOR_SCHEDULED_EXECUTION_SERVICE );
53
84
}
54
85
55
86
/**
@@ -68,7 +99,7 @@ static public ExecutorService newExecutorService() {
68
99
*/
69
100
static public ThreadPoolExecutor newThreadPoolExecutor () {
70
101
return new ThreadPoolExecutor (CoreConstants .CORE_POOL_SIZE , CoreConstants .MAX_POOL_SIZE , 0L ,
71
- TimeUnit .MILLISECONDS , new SynchronousQueue <Runnable >(), THREAD_FACTORY );
102
+ TimeUnit .MILLISECONDS , new SynchronousQueue <Runnable >(), THREAD_FACTORY_FOR_SCHEDULED_EXECUTION_SERVICE );
72
103
}
73
104
74
105
/**
@@ -83,4 +114,23 @@ static public void shutdown(ExecutorService executorService) {
83
114
}
84
115
}
85
116
117
+ /**
118
+ * An alternate implementation of {@linl #newThreadPoolExecutor} which returns a virtual thread per task executor when
119
+ * available.
120
+ *
121
+ * @since 1.3.12/1.4.12
122
+ */
123
+ static public ExecutorService newAlternateThreadPoolExecutor () {
124
+
125
+ if (EnvUtil .isJDK21OrHigher ()) {
126
+ try {
127
+ Method newVirtualTPTMethod = Executors .class .getMethod (NEW_VIRTUAL_TPT_METHOD_NAME );
128
+ return (ExecutorService ) newVirtualTPTMethod .invoke (null );
129
+ } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e ) {
130
+ return newThreadPoolExecutor ();
131
+ }
132
+ } else {
133
+ return newThreadPoolExecutor ();
134
+ }
135
+ }
86
136
}
0 commit comments