43 /**
44 * Represents a task that does not return a result but may throw an exception.
45 */
46 @FunctionalInterface
47 public interface ThrowingRunnable<X extends Throwable> {
48 void run() throws X;
49 }
50
51 /**
52 * Run a task in a virtual thread and wait for it to terminate.
53 * If the task completes with an exception then it is thrown by this method.
54 *
55 * @param name thread name, can be null
56 * @param characteristics thread characteristics
57 * @param task the task to run
58 * @throws X the exception thrown by the task
59 */
60 public static <X extends Throwable> void run(String name,
61 int characteristics,
62 ThrowingRunnable<X> task) throws X {
63 var throwableRef = new AtomicReference<Throwable>();
64 Runnable target = () -> {
65 try {
66 task.run();
67 } catch (Throwable ex) {
68 throwableRef.set(ex);
69 }
70 };
71
72 Thread.Builder builder = Thread.ofVirtual();
73 if (name != null)
74 builder.name(name);
75 if ((characteristics & NO_INHERIT_THREAD_LOCALS) != 0)
76 builder.inheritInheritableThreadLocals(false);
77 Thread thread = builder.start(target);
78
79 // wait for thread to terminate
80 try {
81 while (thread.join(Duration.ofSeconds(10)) == false) {
82 System.out.println("-- " + thread + " --");
83 for (StackTraceElement e : thread.getStackTrace()) {
84 System.out.println(" " + e);
85 }
86 }
87 } catch (InterruptedException e) {
88 throw new RuntimeException(e);
89 }
90
91 Throwable ex = throwableRef.get();
92 if (ex != null) {
93 if (ex instanceof RuntimeException e)
94 throw e;
95 if (ex instanceof Error e)
96 throw e;
|
43 /**
44 * Represents a task that does not return a result but may throw an exception.
45 */
46 @FunctionalInterface
47 public interface ThrowingRunnable<X extends Throwable> {
48 void run() throws X;
49 }
50
51 /**
52 * Run a task in a virtual thread and wait for it to terminate.
53 * If the task completes with an exception then it is thrown by this method.
54 *
55 * @param name thread name, can be null
56 * @param characteristics thread characteristics
57 * @param task the task to run
58 * @throws X the exception thrown by the task
59 */
60 public static <X extends Throwable> void run(String name,
61 int characteristics,
62 ThrowingRunnable<X> task) throws X {
63 Thread.Builder.OfVirtual builder = Thread.ofVirtual();
64 if (name != null)
65 builder.name(name);
66 if ((characteristics & NO_INHERIT_THREAD_LOCALS) != 0)
67 builder.inheritInheritableThreadLocals(false);
68 run(builder, task);
69 }
70
71 /**
72 * Run a task in a virtual thread and wait for it to terminate.
73 * If the task completes with an exception then it is thrown by this method.
74 *
75 * @param builder the builder to create the thread
76 * @param task the task to run
77 * @throws X the exception thrown by the task
78 */
79 public static <X extends Throwable> void run(Thread.Builder.OfVirtual builder,
80 ThrowingRunnable<X> task) throws X {
81 var throwableRef = new AtomicReference<Throwable>();
82 Runnable target = () -> {
83 try {
84 task.run();
85 } catch (Throwable ex) {
86 throwableRef.set(ex);
87 }
88 };
89 Thread thread = builder.start(target);
90
91 // wait for thread to terminate
92 try {
93 while (thread.join(Duration.ofSeconds(10)) == false) {
94 System.out.println("-- " + thread + " --");
95 for (StackTraceElement e : thread.getStackTrace()) {
96 System.out.println(" " + e);
97 }
98 }
99 } catch (InterruptedException e) {
100 throw new RuntimeException(e);
101 }
102
103 Throwable ex = throwableRef.get();
104 if (ex != null) {
105 if (ex instanceof RuntimeException e)
106 throw e;
107 if (ex instanceof Error e)
108 throw e;
|