1089 ThreadFactory factory = VThreadScheduler.virtualThreadFactory(scheduler);
1090 var thread = factory.newThread(() -> {
1091 list.add("A");
1092 var child = factory.newThread(() -> {
1093 list.add("B");
1094 Thread.yield();
1095 list.add("B");
1096 });
1097 child.start();
1098 Thread.yield();
1099 list.add("A");
1100 try { child.join(); } catch (InterruptedException e) { }
1101 });
1102 thread.start();
1103 thread.join();
1104 }
1105 assertEquals(List.of("A", "B", "A", "B"), list);
1106 }
1107
1108 /**
1109 * Test Thread.yield when thread is pinned by native frame.
1110 */
1111 @Test
1112 void testYield2() throws Exception {
1113 assumeTrue(VThreadScheduler.supportsCustomScheduler(), "No support for custom schedulers");
1114 var list = new CopyOnWriteArrayList<String>();
1115 try (ExecutorService scheduler = Executors.newFixedThreadPool(1)) {
1116 ThreadFactory factory = VThreadScheduler.virtualThreadFactory(scheduler);
1117 var thread = factory.newThread(() -> {
1118 list.add("A");
1119 var child = factory.newThread(() -> {
1120 list.add("B");
1121 });
1122 child.start();
1123 VThreadPinner.runPinned(() -> {
1124 Thread.yield(); // pinned so will be a no-op
1125 list.add("A");
1126 });
1127 try { child.join(); } catch (InterruptedException e) { }
1128 });
1129 thread.start();
1130 thread.join();
1131 }
1132 assertEquals(List.of("A", "A", "B"), list);
1133 }
1134
1135 /**
1136 * Test Thread.yield does not consume the thread's parking permit.
1137 */
1138 @Test
1139 void testYield3() throws Exception {
1140 var thread = Thread.ofVirtual().start(() -> {
1141 LockSupport.unpark(Thread.currentThread());
1142 Thread.yield();
1143 LockSupport.park(); // should not park
1144 });
1145 thread.join();
1146 }
1147
1148 /**
1149 * Test Thread.yield does not make available the thread's parking permit.
1150 */
1151 @Test
1152 void testYield4() throws Exception {
1153 var thread = Thread.ofVirtual().start(() -> {
1154 Thread.yield();
1155 LockSupport.park(); // should park
1156 });
1157 try {
1158 await(thread, Thread.State.WAITING);
1159 } finally {
1160 LockSupport.unpark(thread);
1161 thread.join();
1162 }
1163 }
1164
1165 /**
1166 * Test Thread.onSpinWait.
1167 */
1168 @Test
1169 void testOnSpinWait() throws Exception {
1170 VThreadRunner.run(() -> {
1171 Thread me = Thread.currentThread();
1172 Thread.onSpinWait();
1954 void testHoldsLock1() throws Exception {
1955 VThreadRunner.run(() -> {
1956 var lock = new Object();
1957 assertFalse(Thread.holdsLock(lock));
1958 });
1959 }
1960
1961 /**
1962 * Test Thread.holdsLock when lock held.
1963 */
1964 @Test
1965 void testHoldsLock2() throws Exception {
1966 VThreadRunner.run(() -> {
1967 var lock = new Object();
1968 synchronized (lock) {
1969 assertTrue(Thread.holdsLock(lock));
1970 }
1971 });
1972 }
1973
1974 /**
1975 * Test Thread::getStackTrace on unstarted thread.
1976 */
1977 @Test
1978 void testGetStackTraceUnstarted() {
1979 var thread = Thread.ofVirtual().unstarted(() -> { });
1980 StackTraceElement[] stack = thread.getStackTrace();
1981 assertTrue(stack.length == 0);
1982 }
1983
1984 /**
1985 * Test Thread::getStackTrace on thread that has been started but has not run.
1986 */
1987 @Test
1988 void testGetStackTraceStarted() throws Exception {
1989 assumeTrue(VThreadScheduler.supportsCustomScheduler(), "No support for custom schedulers");
1990 Executor scheduler = task -> { };
1991 ThreadFactory factory = VThreadScheduler.virtualThreadFactory(scheduler);
1992 Thread thread = factory.newThread(() -> { });
1993 thread.start();
|
1089 ThreadFactory factory = VThreadScheduler.virtualThreadFactory(scheduler);
1090 var thread = factory.newThread(() -> {
1091 list.add("A");
1092 var child = factory.newThread(() -> {
1093 list.add("B");
1094 Thread.yield();
1095 list.add("B");
1096 });
1097 child.start();
1098 Thread.yield();
1099 list.add("A");
1100 try { child.join(); } catch (InterruptedException e) { }
1101 });
1102 thread.start();
1103 thread.join();
1104 }
1105 assertEquals(List.of("A", "B", "A", "B"), list);
1106 }
1107
1108 /**
1109 * Test Thread.yield releases carrier when virtual thread holds a monitor.
1110 */
1111 @Test
1112 void testYield2() throws Exception {
1113 assumeTrue(VThreadScheduler.supportsCustomScheduler(), "No support for custom schedulers");
1114 var list = new CopyOnWriteArrayList<String>();
1115 try (ExecutorService scheduler = Executors.newFixedThreadPool(1)) {
1116 ThreadFactory factory = VThreadScheduler.virtualThreadFactory(scheduler);
1117 var lock = new Object();
1118 var thread = factory.newThread(() -> {
1119 list.add("A");
1120 var child = factory.newThread(() -> {
1121 list.add("B");
1122 synchronized (lock) {
1123 Thread.yield();
1124 }
1125 list.add("B");
1126 });
1127 child.start();
1128 Thread.yield();
1129 list.add("A");
1130 try { child.join(); } catch (InterruptedException e) { }
1131 });
1132 thread.start();
1133 thread.join();
1134 }
1135 assertEquals(List.of("A", "B", "A", "B"), list);
1136 }
1137
1138 /**
1139 * Test Thread.yield when thread is pinned by native frame.
1140 */
1141 @Test
1142 void testYield3() throws Exception {
1143 assumeTrue(VThreadScheduler.supportsCustomScheduler(), "No support for custom schedulers");
1144 var list = new CopyOnWriteArrayList<String>();
1145 try (ExecutorService scheduler = Executors.newFixedThreadPool(1)) {
1146 ThreadFactory factory = VThreadScheduler.virtualThreadFactory(scheduler);
1147 var thread = factory.newThread(() -> {
1148 list.add("A");
1149 var child = factory.newThread(() -> {
1150 list.add("B");
1151 });
1152 child.start();
1153 VThreadPinner.runPinned(() -> {
1154 Thread.yield(); // pinned so will be a no-op
1155 list.add("A");
1156 });
1157 try { child.join(); } catch (InterruptedException e) { }
1158 });
1159 thread.start();
1160 thread.join();
1161 }
1162 assertEquals(List.of("A", "A", "B"), list);
1163 }
1164
1165 /**
1166 * Test Thread.yield does not consume the thread's parking permit.
1167 */
1168 @Test
1169 void testYield4() throws Exception {
1170 var thread = Thread.ofVirtual().start(() -> {
1171 LockSupport.unpark(Thread.currentThread());
1172 Thread.yield();
1173 LockSupport.park(); // should not park
1174 });
1175 thread.join();
1176 }
1177
1178 /**
1179 * Test Thread.yield does not make available the thread's parking permit.
1180 */
1181 @Test
1182 void testYield5() throws Exception {
1183 var thread = Thread.ofVirtual().start(() -> {
1184 Thread.yield();
1185 LockSupport.park(); // should park
1186 });
1187 try {
1188 await(thread, Thread.State.WAITING);
1189 } finally {
1190 LockSupport.unpark(thread);
1191 thread.join();
1192 }
1193 }
1194
1195 /**
1196 * Test Thread.onSpinWait.
1197 */
1198 @Test
1199 void testOnSpinWait() throws Exception {
1200 VThreadRunner.run(() -> {
1201 Thread me = Thread.currentThread();
1202 Thread.onSpinWait();
1984 void testHoldsLock1() throws Exception {
1985 VThreadRunner.run(() -> {
1986 var lock = new Object();
1987 assertFalse(Thread.holdsLock(lock));
1988 });
1989 }
1990
1991 /**
1992 * Test Thread.holdsLock when lock held.
1993 */
1994 @Test
1995 void testHoldsLock2() throws Exception {
1996 VThreadRunner.run(() -> {
1997 var lock = new Object();
1998 synchronized (lock) {
1999 assertTrue(Thread.holdsLock(lock));
2000 }
2001 });
2002 }
2003
2004 /**
2005 * Test Thread.holdsLock when lock held by carrier thread.
2006 */
2007 @Disabled
2008 @Test
2009 void testHoldsLock3() throws Exception {
2010 assumeTrue(VThreadScheduler.supportsCustomScheduler(), "No support for custom schedulers");
2011
2012 Object lock = new Object();
2013
2014 // carrier thread runs all tasks while holding the lock
2015 ThreadFactory carrierThreadFactory = task -> Thread.ofPlatform().unstarted(() -> {
2016 synchronized (lock) {
2017 task.run();
2018 }
2019 });
2020 try (ExecutorService pool = Executors.newSingleThreadExecutor(carrierThreadFactory)) {
2021 Executor scheduler = task -> pool.submit(task::run);
2022 ThreadFactory factory = VThreadScheduler.virtualThreadFactory(scheduler);
2023
2024 // start virtual that tests if it holds the lock
2025 var result = new AtomicReference<Boolean>();
2026 Thread vthread = factory.newThread(() -> {
2027 result.set(Thread.holdsLock(lock));
2028 });
2029 vthread.start();
2030 vthread.join();
2031 boolean holdsLock = result.get();
2032 assertFalse(holdsLock, "Thread.holdsLock should return false");
2033 }
2034 }
2035
2036 /**
2037 * Test Thread::getStackTrace on unstarted thread.
2038 */
2039 @Test
2040 void testGetStackTraceUnstarted() {
2041 var thread = Thread.ofVirtual().unstarted(() -> { });
2042 StackTraceElement[] stack = thread.getStackTrace();
2043 assertTrue(stack.length == 0);
2044 }
2045
2046 /**
2047 * Test Thread::getStackTrace on thread that has been started but has not run.
2048 */
2049 @Test
2050 void testGetStackTraceStarted() throws Exception {
2051 assumeTrue(VThreadScheduler.supportsCustomScheduler(), "No support for custom schedulers");
2052 Executor scheduler = task -> { };
2053 ThreadFactory factory = VThreadScheduler.virtualThreadFactory(scheduler);
2054 Thread thread = factory.newThread(() -> { });
2055 thread.start();
|