3939import java .util .concurrent .Executors ;
4040import java .util .concurrent .RejectedExecutionException ;
4141import java .util .concurrent .ThreadFactory ;
42+ import java .util .concurrent .atomic .AtomicReference ;
4243import java .util .concurrent .locks .LockSupport ;
4344import java .util .stream .Collectors ;
4445
@@ -75,12 +76,12 @@ void testVirtualThreadStartAndEnd() throws Exception {
7576 }
7677
7778 Map <String , Integer > events = sumEvents (recording );
78- System .out .println (events );
79+ System .err .println (events );
7980
8081 int startCount = events .getOrDefault ("jdk.VirtualThreadStart" , 0 );
8182 int endCount = events .getOrDefault ("jdk.VirtualThreadEnd" , 0 );
82- assertTrue ( startCount == 100 );
83- assertTrue ( endCount == 100 );
83+ assertEquals ( 100 , startCount );
84+ assertEquals ( 100 , endCount );
8485 }
8586 }
8687
@@ -89,35 +90,51 @@ void testVirtualThreadStartAndEnd() throws Exception {
8990 */
9091 @ Test
9192 void testVirtualThreadPinned () throws Exception {
93+ Runnable [] parkers = new Runnable [] {
94+ () -> LockSupport .park (),
95+ () -> LockSupport .parkNanos (Duration .ofDays (1 ).toNanos ())
96+ };
97+
9298 try (Recording recording = new Recording ()) {
93- recording .enable ("jdk.VirtualThreadPinned" )
94- .withThreshold (Duration .ofMillis (500 ));
99+ recording .enable ("jdk.VirtualThreadPinned" );
95100
96- // execute task in a virtual thread, carrier thread is pinned 3 times.
97101 recording .start ();
98- ThreadFactory factory = Thread .ofVirtual ().factory ();
99- try (var executor = Executors .newThreadPerTaskExecutor (factory )) {
100- executor .submit (() -> {
101- synchronized (lock ) {
102- // pinned, duration < 500ms
103- Thread .sleep (1 );
104-
105- // pinned, duration > 500ms
106- Thread .sleep (Duration .ofSeconds (3 ));
107- Thread .sleep (Duration .ofSeconds (3 ));
102+ try (var executor = Executors .newVirtualThreadPerTaskExecutor ()) {
103+ for (Runnable parker : parkers ) {
104+ // execute parking task in virtual thread
105+ var threadRef = new AtomicReference <Thread >();
106+ executor .submit (() -> {
107+ threadRef .set (Thread .currentThread ());
108+ synchronized (lock ) {
109+ parker .run (); // should pin carrier
110+ }
111+ });
112+
113+ // wait for the task to start and the virtual thread to park
114+ Thread thread ;
115+ while ((thread = threadRef .get ()) == null ) {
116+ Thread .sleep (10 );
108117 }
109- return null ;
110- });
118+ try {
119+ Thread .State state = thread .getState ();
120+ while (state != Thread .State .WAITING && state != Thread .State .TIMED_WAITING ) {
121+ Thread .sleep (10 );
122+ state = thread .getState ();
123+ }
124+ } finally {
125+ LockSupport .unpark (thread );
126+ }
127+ }
111128 } finally {
112129 recording .stop ();
113130 }
114131
115132 Map <String , Integer > events = sumEvents (recording );
116- System .out .println (events );
133+ System .err .println (events );
117134
118- // should have two pinned events recorded
135+ // should have a pinned event for each park
119136 int pinnedCount = events .getOrDefault ("jdk.VirtualThreadPinned" , 0 );
120- assertTrue ( pinnedCount == 2 );
137+ assertEquals ( parkers . length , pinnedCount );
121138 }
122139 }
123140
@@ -164,10 +181,10 @@ void testVirtualThreadSubmitFailed() throws Exception {
164181 }
165182
166183 Map <String , Integer > events = sumEvents (recording );
167- System .out .println (events );
184+ System .err .println (events );
168185
169186 int count = events .getOrDefault ("jdk.VirtualThreadSubmitFailed" , 0 );
170- assertTrue ( count == 2 );
187+ assertEquals ( 2 , count );
171188 }
172189 }
173190
0 commit comments