< prev index next > test/jdk/java/lang/Thread/virtual/ThreadAPI.java
Print this page
}
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(() -> {
/**
* 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
});
/**
* 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 {
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 >