1 /*
2 * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
173 *
174 * <p> Unless otherwise specified, passing a {@code null} argument to a constructor
175 * or method in this class will cause a {@link NullPointerException} to be thrown.
176 *
177 * @implNote
178 * In the JDK Reference Implementation, the virtual thread scheduler may be configured
179 * with the following system properties:
180 * <table class="striped">
181 * <caption style="display:none">System properties</caption>
182 * <thead>
183 * <tr>
184 * <th scope="col">System property</th>
185 * <th scope="col">Description</th>
186 * </tr>
187 * </thead>
188 * <tbody>
189 * <tr>
190 * <th scope="row">
191 * {@systemProperty jdk.virtualThreadScheduler.parallelism}
192 * </th>
193 * <td> The number of platform threads available for scheduling virtual
194 * threads. It defaults to the number of available processors. </td>
195 * </tr>
196 * <tr>
197 * <th scope="row">
198 * {@systemProperty jdk.virtualThreadScheduler.maxPoolSize}
199 * </th>
200 * <td> The maximum number of platform threads available to the scheduler.
201 * It defaults to 256. </td>
202 * </tr>
203 * </tbody>
204 * </table>
205 *
206 * @since 1.0
207 */
208 public class Thread implements Runnable {
209 /* Make sure registerNatives is the first thing <clinit> does. */
210 private static native void registerNatives();
211 static {
212 registerNatives();
213 }
214
1392 }
1393
1394 /**
1395 * Schedules this thread to begin execution in the given thread container.
1396 * @throws IllegalStateException if the container is shutdown or closed
1397 * @throws IllegalThreadStateException if the thread has already been started
1398 */
1399 void start(ThreadContainer container) {
1400 synchronized (this) {
1401 // zero status corresponds to state "NEW".
1402 if (holder.threadStatus != 0)
1403 throw new IllegalThreadStateException();
1404
1405 // bind thread to container
1406 if (this.container != null)
1407 throw new IllegalThreadStateException();
1408 setThreadContainer(container);
1409
1410 // start thread
1411 boolean started = false;
1412 container.onStart(this); // may throw
1413 try {
1414 // scoped values may be inherited
1415 inheritScopedValueBindings(container);
1416
1417 start0();
1418 started = true;
1419 } finally {
1420 if (!started) {
1421 container.onExit(this);
1422 }
1423 }
1424 }
1425 }
1426
1427 private native void start0();
1428
1429 /**
1430 * This method is run by the thread when it executes. Subclasses of {@code
1431 * Thread} may override this method.
1432 *
1433 * <p> This method is not intended to be invoked directly. If this thread is a
1434 * platform thread created with a {@link Runnable} task then invoking this method
1435 * will invoke the task's {@code run} method. If this thread is a virtual thread
1436 * then invoking this method directly does nothing.
1437 *
1438 * @implSpec The default implementation executes the {@link Runnable} task that
1439 * the {@code Thread} was created with. If the thread was created without a task
1440 * then this method does nothing.
1441 */
1470 if (uncaughtExceptionHandler != null)
1471 uncaughtExceptionHandler = null;
1472 if (nioBlocker != null)
1473 nioBlocker = null;
1474 }
1475
1476 /**
1477 * This method is called by the VM to give a Thread
1478 * a chance to clean up before it actually exits.
1479 */
1480 private void exit() {
1481 try {
1482 // pop any remaining scopes from the stack, this may block
1483 if (headStackableScopes != null) {
1484 StackableScope.popAll();
1485 }
1486 } finally {
1487 // notify container that thread is exiting
1488 ThreadContainer container = threadContainer();
1489 if (container != null) {
1490 container.onExit(this);
1491 }
1492 }
1493
1494 try {
1495 if (threadLocals != null && TerminatingThreadLocal.REGISTRY.isPresent()) {
1496 TerminatingThreadLocal.threadTerminated();
1497 }
1498 } finally {
1499 clearReferences();
1500 }
1501 }
1502
1503 /**
1504 * Throws {@code UnsupportedOperationException}.
1505 *
1506 * @throws UnsupportedOperationException always
1507 *
1508 * @deprecated This method was originally specified to "stop" a victim
1509 * thread by causing the victim thread to throw a {@link ThreadDeath}.
1510 * It was inherently unsafe. Stopping a thread caused it to unlock
|
1 /*
2 * Copyright (c) 1994, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
173 *
174 * <p> Unless otherwise specified, passing a {@code null} argument to a constructor
175 * or method in this class will cause a {@link NullPointerException} to be thrown.
176 *
177 * @implNote
178 * In the JDK Reference Implementation, the virtual thread scheduler may be configured
179 * with the following system properties:
180 * <table class="striped">
181 * <caption style="display:none">System properties</caption>
182 * <thead>
183 * <tr>
184 * <th scope="col">System property</th>
185 * <th scope="col">Description</th>
186 * </tr>
187 * </thead>
188 * <tbody>
189 * <tr>
190 * <th scope="row">
191 * {@systemProperty jdk.virtualThreadScheduler.parallelism}
192 * </th>
193 * <td> The scheduler's target parallelism. It defaults to the number of
194 * available processors. </td>
195 * </tr>
196 * <tr>
197 * <th scope="row">
198 * {@systemProperty jdk.virtualThreadScheduler.maxPoolSize}
199 * </th>
200 * <td> The maximum number of platform threads available to the scheduler.
201 * It defaults to 256. </td>
202 * </tr>
203 * </tbody>
204 * </table>
205 *
206 * @since 1.0
207 */
208 public class Thread implements Runnable {
209 /* Make sure registerNatives is the first thing <clinit> does. */
210 private static native void registerNatives();
211 static {
212 registerNatives();
213 }
214
1392 }
1393
1394 /**
1395 * Schedules this thread to begin execution in the given thread container.
1396 * @throws IllegalStateException if the container is shutdown or closed
1397 * @throws IllegalThreadStateException if the thread has already been started
1398 */
1399 void start(ThreadContainer container) {
1400 synchronized (this) {
1401 // zero status corresponds to state "NEW".
1402 if (holder.threadStatus != 0)
1403 throw new IllegalThreadStateException();
1404
1405 // bind thread to container
1406 if (this.container != null)
1407 throw new IllegalThreadStateException();
1408 setThreadContainer(container);
1409
1410 // start thread
1411 boolean started = false;
1412 container.add(this); // may throw
1413 try {
1414 // scoped values may be inherited
1415 inheritScopedValueBindings(container);
1416
1417 start0();
1418 started = true;
1419 } finally {
1420 if (!started) {
1421 container.remove(this);
1422 }
1423 }
1424 }
1425 }
1426
1427 private native void start0();
1428
1429 /**
1430 * This method is run by the thread when it executes. Subclasses of {@code
1431 * Thread} may override this method.
1432 *
1433 * <p> This method is not intended to be invoked directly. If this thread is a
1434 * platform thread created with a {@link Runnable} task then invoking this method
1435 * will invoke the task's {@code run} method. If this thread is a virtual thread
1436 * then invoking this method directly does nothing.
1437 *
1438 * @implSpec The default implementation executes the {@link Runnable} task that
1439 * the {@code Thread} was created with. If the thread was created without a task
1440 * then this method does nothing.
1441 */
1470 if (uncaughtExceptionHandler != null)
1471 uncaughtExceptionHandler = null;
1472 if (nioBlocker != null)
1473 nioBlocker = null;
1474 }
1475
1476 /**
1477 * This method is called by the VM to give a Thread
1478 * a chance to clean up before it actually exits.
1479 */
1480 private void exit() {
1481 try {
1482 // pop any remaining scopes from the stack, this may block
1483 if (headStackableScopes != null) {
1484 StackableScope.popAll();
1485 }
1486 } finally {
1487 // notify container that thread is exiting
1488 ThreadContainer container = threadContainer();
1489 if (container != null) {
1490 container.remove(this);
1491 }
1492 }
1493
1494 try {
1495 if (threadLocals != null && TerminatingThreadLocal.REGISTRY.isPresent()) {
1496 TerminatingThreadLocal.threadTerminated();
1497 }
1498 } finally {
1499 clearReferences();
1500 }
1501 }
1502
1503 /**
1504 * Throws {@code UnsupportedOperationException}.
1505 *
1506 * @throws UnsupportedOperationException always
1507 *
1508 * @deprecated This method was originally specified to "stop" a victim
1509 * thread by causing the victim thread to throw a {@link ThreadDeath}.
1510 * It was inherently unsafe. Stopping a thread caused it to unlock
|