< prev index next >

test/lib/jdk/test/lib/thread/VThreadScheduler.java

Print this page

  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 package jdk.test.lib.thread;
 25 
 26 import java.lang.reflect.Constructor;
 27 import java.lang.reflect.Field;

 28 import java.lang.reflect.InvocationTargetException;
 29 import java.util.concurrent.Executor;
 30 import java.util.concurrent.Executors;
 31 import java.util.concurrent.ThreadFactory;
 32 
 33 /**
 34  * Helper class to allow tests run virtual threads with a custom scheduler.
 35  *
 36  * Tests using this class need to open java.base/java.lang.
 37  */
 38 public class VThreadScheduler {
 39     private VThreadScheduler() { }
 40 




















 41     /**
 42      * Returns the scheduler for the given virtual thread.
 43      */
 44     public static Executor scheduler(Thread thread) {
 45         if (!thread.isVirtual())
 46             throw new IllegalArgumentException("Not a virtual thread");
 47         try {
 48             Field scheduler = Class.forName("java.lang.VirtualThread")
 49                     .getDeclaredField("scheduler");
 50             scheduler.setAccessible(true);
 51             return (Executor) scheduler.get(thread);
 52         } catch (Exception e) {
 53             throw new RuntimeException(e);
 54         }
 55     }
 56 
 57     /**
 58      * Return true if custom schedulers are supported.
 59      */
 60     public static boolean supportsCustomScheduler() {
 61         try (var pool = Executors.newCachedThreadPool()) {
 62             try {
 63                 virtualThreadBuilder(pool);
 64                 return true;
 65             } catch (UnsupportedOperationException e) {
 66                 return false;
 67             }
 68         }
 69     }
 70 
 71     /**
 72      * Returns a builder to create virtual threads that use the given scheduler.
 73      * @throws UnsupportedOperationException if custom schedulers are not supported
 74      */
 75     public static Thread.Builder.OfVirtual virtualThreadBuilder(Executor scheduler) {
 76         try {
 77             Class<?> clazz = Class.forName("java.lang.ThreadBuilders$VirtualThreadBuilder");
 78             Constructor<?> ctor = clazz.getDeclaredConstructor(Executor.class);
 79             ctor.setAccessible(true);
 80             return (Thread.Builder.OfVirtual) ctor.newInstance(scheduler);
 81         } catch (InvocationTargetException e) {
 82             Throwable cause = e.getCause();
 83             if (cause instanceof RuntimeException re) {
 84                 throw re;
 85             }
 86             throw new RuntimeException(e);
 87         } catch (Exception e) {
 88             throw new RuntimeException(e);
 89         }


 90     }
 91 
 92     /**
 93      * Returns a ThreadFactory to create virtual threads that use the given scheduler.
 94      * @throws UnsupportedOperationException if custom schedulers are not supported
 95      */
 96     public static ThreadFactory virtualThreadFactory(Executor scheduler) {
 97         return virtualThreadBuilder(scheduler).factory();
 98     }




 99 }

  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 package jdk.test.lib.thread;
 25 

 26 import java.lang.reflect.Field;
 27 import java.lang.reflect.Method;
 28 import java.lang.reflect.InvocationTargetException;
 29 import java.util.concurrent.Executor;
 30 import java.util.concurrent.Executors;
 31 import java.util.concurrent.ThreadFactory;
 32 
 33 /**
 34  * Helper class to allow tests run virtual threads with a custom scheduler.
 35  *
 36  * Tests using this class need to open java.base/java.lang.
 37  */
 38 public class VThreadScheduler {
 39     private VThreadScheduler() { }
 40 
 41     /**
 42      * Returns the default virtual thread scheduler.
 43      */
 44     public static Thread.VirtualThreadScheduler defaultScheduler() {
 45         try {
 46             Method m = Class.forName("java.lang.VirtualThread")
 47                     .getDeclaredMethod("defaultScheduler");
 48             m.setAccessible(true);
 49             return (Thread.VirtualThreadScheduler ) m.invoke(null);
 50         } catch (InvocationTargetException e) {
 51             Throwable cause = e.getCause();
 52             if (cause instanceof RuntimeException re) {
 53                 throw re;
 54             }
 55             throw new RuntimeException(e);
 56         } catch (Exception e) {
 57             throw new RuntimeException(e);
 58         }
 59     }
 60 
 61     /**
 62      * Returns the scheduler for the given virtual thread.
 63      */
 64     public static Thread.VirtualThreadScheduler scheduler(Thread thread) {
 65         if (!thread.isVirtual())
 66             throw new IllegalArgumentException("Not a virtual thread");
 67         try {
 68             Field scheduler = Class.forName("java.lang.VirtualThread")
 69                     .getDeclaredField("scheduler");
 70             scheduler.setAccessible(true);
 71             return (Thread.VirtualThreadScheduler) scheduler.get(thread);
 72         } catch (Exception e) {
 73             throw new RuntimeException(e);
 74         }
 75     }
 76 
 77     /**
 78      * Return true if custom schedulers are supported.
 79      */
 80     public static boolean supportsCustomScheduler() {
 81         try (var pool = Executors.newCachedThreadPool()) {
 82             try {
 83                 virtualThreadBuilder(pool);
 84                 return true;
 85             } catch (UnsupportedOperationException e) {
 86                 return false;
 87             }
 88         }
 89     }
 90 
 91     /**
 92      * Returns a builder to create virtual threads that use the given scheduler.
 93      * @throws UnsupportedOperationException if custom schedulers are not supported
 94      */
 95     @SuppressWarnings("restricted")
 96     public static Thread.Builder.OfVirtual virtualThreadBuilder(Thread.VirtualThreadScheduler scheduler) {
 97         return Thread.ofVirtual().scheduler(scheduler);
 98     }
 99 
100     public static Thread.Builder.OfVirtual virtualThreadBuilder(Executor executor) {
101         var scheduler = new Thread.VirtualThreadScheduler() {
102             @Override
103             public void onStart(Thread.VirtualThreadTask task) {
104                 executor.execute(task);
105             }
106             @Override
107             public void onContinue(Thread.VirtualThreadTask task) {
108                 executor.execute(task);
109             }
110         };
111         return virtualThreadBuilder(scheduler);
112     }
113 
114     /**
115      * Returns a ThreadFactory to create virtual threads that use the given scheduler.
116      * @throws UnsupportedOperationException if custom schedulers are not supported
117      */
118     public static ThreadFactory virtualThreadFactory(Thread.VirtualThreadScheduler scheduler) {
119         return virtualThreadBuilder(scheduler).factory();
120     }
121 
122     public static ThreadFactory virtualThreadFactory(Executor executor) {
123         return virtualThreadBuilder(executor).factory();
124     }
125 }
< prev index next >