1 /* 2 * Hunt - A refined core library for D programming language. 3 * 4 * Copyright (C) 2018-2019 HuntLabs 5 * 6 * Website: https://www.huntlabs.net/ 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.concurrency.ThreadFactory; 13 14 import hunt.concurrency.atomic.AtomicHelper; 15 import hunt.concurrency.thread.ThreadEx; 16 17 import hunt.Functions; 18 import hunt.util.Common; 19 20 import core.thread; 21 import std.conv; 22 23 /** 24 * An object that creates new threads on demand. Using thread factories 25 * removes hardwiring of calls to {@link Thread#Thread(Runnable) new Thread}, 26 * enabling applications to use special thread subclasses, priorities, etc. 27 * 28 * <p> 29 * The simplest implementation of this interface is just: 30 * <pre> {@code 31 * class SimpleThreadFactory implements ThreadFactory { 32 * public Thread newThread(Runnable r) { 33 * return new Thread(r); 34 * } 35 * }}</pre> 36 * 37 * The {@link Executors#defaultThreadFactory} method provides a more 38 * useful simple implementation, that sets the created thread context 39 * to known values before returning it. 40 * @since 1.5 41 * @author Doug Lea 42 */ 43 interface ThreadFactory { 44 45 /** 46 * Returns a default thread factory used to create new threads. 47 * This factory creates all new threads used by an Executor in the 48 * same {@link ThreadGroupEx}. If there is a {@link 49 * java.lang.SecurityManager}, it uses the group of {@link 50 * System#getSecurityManager}, else the group of the thread 51 * invoking this {@code defaultThreadFactory} method. Each new 52 * thread is created as a non-daemon thread with priority set to 53 * the smaller of {@code Thread.PRIORITY_DEFAULT} and the maximum 54 * priority permitted in the thread group. New threads have names 55 * accessible via {@link Thread#getName} of 56 * <em>pool-N-thread-M</em>, where <em>N</em> is the sequence 57 * number of this factory, and <em>M</em> is the sequence number 58 * of the thread created by this factory. 59 * @return a thread factory 60 */ 61 static ThreadFactory defaultThreadFactory() { 62 return new DefaultThreadFactory(); 63 } 64 65 /** 66 * Constructs a new {@code Thread}. Implementations may also initialize 67 * priority, name, daemon status, {@code ThreadGroupEx}, etc. 68 * 69 * @param r a runnable to be executed by new thread instance 70 * @return constructed thread, or {@code null} if the request to 71 * create a thread is rejected 72 */ 73 final Thread newThread(Runnable r) { 74 return newThread({ r.run(); }); 75 } 76 77 Thread newThread(Action dg ); 78 } 79 80 81 /** 82 * The default thread factory. 83 */ 84 private class DefaultThreadFactory : ThreadFactory { 85 private static shared(int) poolNumber = 1; 86 private ThreadGroupEx group; 87 private shared(int) threadNumber = 1; 88 private string namePrefix; 89 90 this() { 91 // SecurityManager s = System.getSecurityManager(); 92 // group = (s !is null) ? s.getThreadGroup() : 93 // Thread.getThis().getThreadGroup(); 94 int n = AtomicHelper.getAndIncrement(poolNumber); 95 namePrefix = "pool-" ~ n.to!string() ~ "-thread-"; 96 } 97 98 99 Thread newThread(Action dg ) { 100 int n = AtomicHelper.getAndIncrement(threadNumber); 101 102 Thread t = new ThreadEx(dg); 103 t.name = namePrefix ~ n.to!string(); 104 t.isDaemon = false; 105 // version(Posix) { 106 // t.priority = Thread.PRIORITY_DEFAULT; 107 // } 108 109 return t; 110 } 111 } 112 113 114 /** 115 * Thread factory capturing access control context and class loader. 116 */ 117 // private class PrivilegedThreadFactory : DefaultThreadFactory { 118 // // AccessControlContext acc; 119 // // ClassLoader ccl; 120 121 // this() { 122 // super(); 123 // SecurityManager sm = System.getSecurityManager(); 124 // if (sm !is null) { 125 // // Calls to getContextClassLoader from this class 126 // // never trigger a security check, but we check 127 // // whether our callers have this permission anyways. 128 // sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); 129 130 // // Fail fast 131 // sm.checkPermission(new RuntimePermission("setContextClassLoader")); 132 // } 133 // this.acc = AccessController.getContext(); 134 // this.ccl = Thread.getThis().getContextClassLoader(); 135 // } 136 137 // Thread newThread(Runnable r) { 138 // return super.newThread(new Runnable() { 139 // void run() { 140 // AccessController.doPrivileged(new PrivilegedAction<>() { 141 // Void run() { 142 // Thread.getThis().setContextClassLoader(ccl); 143 // r.run(); 144 // return null; 145 // } 146 // }, acc); 147 // } 148 // }); 149 // } 150 // }