Last active
          October 28, 2025 19:41 
        
      - 
      
- 
        Save fogus/b837e5db38ecff733ec40fd09b6b6be0 to your computer and use it in GitHub Desktop. 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | package fogus.rete; | |
| import java.lang.management.ManagementFactory; | |
| import java.lang.management.RuntimeMXBean; | |
| import java.lang.ref.WeakReference; | |
| import java.util.concurrent.CompletableFuture; | |
| import java.util.concurrent.ExecutionException; | |
| import java.util.concurrent.ThreadFactory; | |
| public class Tester { | |
| static CompletableFuture<String> future = new CompletableFuture<>(); | |
| private static WeakReference<Thread> startAndWrap(ThreadFactory factory, Runnable task) { | |
| Thread thread = factory.newThread(task); | |
| thread.start(); | |
| System.out.println("THREAD KS == " + Thread.getAllStackTraces().keySet()); | |
| System.out.println(" has? " + Thread.getAllStackTraces().containsKey(thread)); | |
| return new WeakReference<>(thread); | |
| } | |
| @SuppressWarnings("removal") | |
| public static void main(String[] args) throws InterruptedException { | |
| String value = System.getProperty("jdk.trackAllThreads"); | |
| System.out.println("jdk.trackAllThreads = " + value); | |
| RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean(); | |
| String processName = runtimeMXBean.getName(); | |
| long pid = Long.parseLong(processName.split("@")[0]); | |
| System.out.println("The Process ID (PID) of this Java application is: " + pid); | |
| ThreadFactory virtualThreadFactory = Thread.ofVirtual() | |
| .name("vthread-", 0) | |
| .uncaughtExceptionHandler((thread, throwable) -> { | |
| System.err.println("Exception in " + thread.getName() + ": " + throwable.getMessage()); | |
| }) | |
| .factory(); | |
| WeakReference ref = startAndWrap(virtualThreadFactory, () -> { | |
| try { | |
| System.out.println("Virtual thread blocking on future..."); | |
| String result = future.get(); // This will block indefinitely | |
| System.out.println("Got result: " + result); | |
| } catch (InterruptedException | ExecutionException e) { | |
| System.out.println("Exception in vthread: " + e.getMessage()); | |
| } | |
| }); | |
| // Give the vthread time to start and block | |
| Thread.sleep(100); | |
| // Drop the future reference | |
| System.out.println("Dropping future reference..."); | |
| future = null; | |
| // Force a GC | |
| System.out.println("Forcing GC..."); | |
| System.gc(); | |
| System.runFinalization(); | |
| System.gc(); | |
| // Keep main thread alive to observe the state | |
| Thread.sleep(6000); | |
| System.out.println("weakref value is " + ref.get()); | |
| System.out.println("Exiting main thread."); | |
| } | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment