< prev index next >

src/java.base/share/classes/java/lang/Thread.java

Print this page

   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
< prev index next >