< prev index next >

test/jdk/java/lang/Thread/virtual/ThreadAPI.java

Print this page
@@ -1104,14 +1104,44 @@
          }
          assertEquals(List.of("A", "B", "A", "B"), list);
      }
  
      /**
-      * Test Thread.yield when thread is pinned by native frame.
+      * Test Thread.yield releases carrier when virtual thread holds a monitor.
       */
      @Test
      void testYield2() throws Exception {
+         assumeTrue(VThreadScheduler.supportsCustomScheduler(), "No support for custom schedulers");
+         var list = new CopyOnWriteArrayList<String>();
+         try (ExecutorService scheduler = Executors.newFixedThreadPool(1)) {
+             ThreadFactory factory = VThreadScheduler.virtualThreadFactory(scheduler);
+             var lock = new Object();
+             var thread = factory.newThread(() -> {
+                 list.add("A");
+                 var child = factory.newThread(() -> {
+                     list.add("B");
+                     synchronized (lock) {
+                         Thread.yield();
+                     }
+                     list.add("B");
+                 });
+                 child.start();
+                 Thread.yield();
+                 list.add("A");
+                 try { child.join(); } catch (InterruptedException e) { }
+             });
+             thread.start();
+             thread.join();
+         }
+         assertEquals(List.of("A", "B", "A", "B"), list);
+     }
+ 
+     /**
+      * Test Thread.yield when thread is pinned by native frame.
+      */
+     @Test
+     void testYield3() throws Exception {
          assumeTrue(VThreadScheduler.supportsCustomScheduler(), "No support for custom schedulers");
          var list = new CopyOnWriteArrayList<String>();
          try (ExecutorService scheduler = Executors.newFixedThreadPool(1)) {
              ThreadFactory factory = VThreadScheduler.virtualThreadFactory(scheduler);
              var thread = factory.newThread(() -> {

@@ -1134,11 +1164,11 @@
  
      /**
       * Test Thread.yield does not consume the thread's parking permit.
       */
      @Test
-     void testYield3() throws Exception {
+     void testYield4() throws Exception {
          var thread = Thread.ofVirtual().start(() -> {
              LockSupport.unpark(Thread.currentThread());
              Thread.yield();
              LockSupport.park();  // should not park
          });

@@ -1147,11 +1177,11 @@
  
      /**
       * Test Thread.yield does not make available the thread's parking permit.
       */
      @Test
-     void testYield4() throws Exception {
+     void testYield5() throws Exception {
          var thread = Thread.ofVirtual().start(() -> {
              Thread.yield();
              LockSupport.park();  // should park
          });
          try {

@@ -1969,10 +1999,42 @@
                  assertTrue(Thread.holdsLock(lock));
              }
          });
      }
  
+     /**
+      * Test Thread.holdsLock when lock held by carrier thread.
+      */
+     @Disabled
+     @Test
+     void testHoldsLock3() throws Exception {
+         assumeTrue(VThreadScheduler.supportsCustomScheduler(), "No support for custom schedulers");
+ 
+         Object lock = new Object();
+ 
+         // carrier thread runs all tasks while holding the lock
+         ThreadFactory carrierThreadFactory = task -> Thread.ofPlatform().unstarted(() -> {
+             synchronized (lock) {
+                 task.run();
+             }
+         });
+         try (ExecutorService pool = Executors.newSingleThreadExecutor(carrierThreadFactory)) {
+             Executor scheduler = task -> pool.submit(task::run);
+             ThreadFactory factory = VThreadScheduler.virtualThreadFactory(scheduler);
+ 
+             // start virtual that tests if it holds the lock
+             var result = new AtomicReference<Boolean>();
+             Thread vthread = factory.newThread(() -> {
+                 result.set(Thread.holdsLock(lock));
+             });
+             vthread.start();
+             vthread.join();
+             boolean holdsLock = result.get();
+             assertFalse(holdsLock, "Thread.holdsLock should return false");
+         }
+     }
+ 
      /**
       * Test Thread::getStackTrace on unstarted thread.
       */
      @Test
      void testGetStackTraceUnstarted() {
< prev index next >