001/* 002 * $Id: ComputerThreads.java 6010 2020-04-01 10:39:15Z kredel $ 003 */ 004 005package edu.jas.kern; 006 007 008import java.util.List; 009import java.util.concurrent.BlockingQueue; 010import java.util.concurrent.ExecutorService; 011import java.util.concurrent.Executors; 012import java.util.concurrent.ThreadPoolExecutor; 013import java.util.concurrent.TimeUnit; 014 015import org.apache.logging.log4j.LogManager; 016import org.apache.logging.log4j.Logger; 017 018 019/** 020 * ComputerThreads, provides global thread / executor service. 021 * <p> 022 * <b>Usage:</b> To obtain a reference to the thread pool use 023 * <code>ComputerThreads.getPool()</code>. Once a pool has been created it must 024 * be shutdown with <code>ComputerThreads.terminate()</code> to exit JAS. 025 * </p> 026 * @author Heinz Kredel 027 */ 028 029public class ComputerThreads { 030 031 032 private static final Logger logger = LogManager.getLogger(ComputerThreads.class); 033 034 035 // private static final boolean debug = logger.isInfoEnabled(); //logger.isInfoEnabled(); 036 037 038 /** 039 * Flag for thread usage. <b>Note:</b> Only introduced because Google app 040 * engine does not support threads. 041 * @see edu.jas.ufd.GCDFactory#getProxy(edu.jas.structure.RingFactory) 042 */ 043 public static boolean NO_THREADS = false; 044 045 046 /** 047 * Number of processors. 048 */ 049 public static final int N_CPUS = Runtime.getRuntime().availableProcessors(); 050 051 052 /* 053 * Core number of threads. 054 * N_CPUS x 1.5, x 2, x 2.5, min 3, ?. 055 */ 056 public static final int N_THREADS = (N_CPUS < 3 ? 3 : N_CPUS + N_CPUS / 2); 057 058 059 //public static final int N_THREADS = ( N_CPUS < 3 ? 5 : 3*N_CPUS ); 060 061 062 /** 063 * Timeout for timed execution. 064 * @see edu.jas.fd.SGCDParallelProxy 065 */ 066 static long timeout = 10L; //-1L; 067 068 069 /** 070 * TimeUnit for timed execution. 071 * @see edu.jas.fd.SGCDParallelProxy 072 */ 073 static TimeUnit timeunit = TimeUnit.SECONDS; 074 075 076 /* 077 * Saturation policy. 078 */ 079 //public static final RejectedExecutionHandler REH = new ThreadPoolExecutor.CallerRunsPolicy(); 080 //public static final RejectedExecutionHandler REH = new ThreadPoolExecutor.AbortPolicy(); 081 082 /** 083 * ExecutorService thread pool. 084 */ 085 //static ThreadPoolExecutor pool = null; 086 static ExecutorService pool = null; 087 088 089 /** 090 * No public constructor. 091 */ 092 private ComputerThreads() { 093 } 094 095 096 /** 097 * Test if a pool is running. 098 * @return true if a thread pool has been started or is running, else false. 099 */ 100 public static synchronized boolean isRunning() { 101 if (pool == null) { 102 return false; 103 } 104 if (pool.isTerminated() || pool.isShutdown()) { 105 return false; 106 } 107 return true; 108 } 109 110 111 /** 112 * Get the thread pool. 113 * @return pool ExecutorService. 114 */ 115 public static synchronized ExecutorService getPool() { 116 if (pool == null) { 117 // workpile = new ArrayBlockingQueue<Runnable>(Q_CAPACITY); 118 // pool = Executors.newFixedThreadPool(N_THREADS); 119 pool = Executors.newCachedThreadPool(); 120 // pool = new ThreadPoolExecutor(N_CPUS, N_THREADS, 121 // 100L, TimeUnit.MILLISECONDS, 122 // workpile, REH); 123 // pool = new ThreadPoolExecutor(N_CPUS, N_THREADS, 124 // 1000L, TimeUnit.MILLISECONDS, 125 // workpile); 126 } 127 //System.out.println("pool_init = " + pool); 128 return pool; 129 //return Executors.unconfigurableExecutorService(pool); 130 131 /* not useful, is not run from jython 132 final GCDProxy<C> proxy = this; 133 Runtime.getRuntime().addShutdownHook( 134 new Thread() { 135 public void run() { 136 logger.info("running shutdown hook"); 137 proxy.terminate(); 138 } 139 } 140 ); 141 */ 142 } 143 144 145 /** 146 * Stop execution. 147 */ 148 public static synchronized void terminate() { 149 if (pool == null) { 150 return; 151 } 152 if (pool instanceof ThreadPoolExecutor) { 153 ThreadPoolExecutor tpe = (ThreadPoolExecutor) pool; 154 //logger.info("task queue size " + Q_CAPACITY); 155 //logger.info("reject execution handler" + REH.getClass().getName()); 156 logger.info("number of CPUs " + N_CPUS); 157 logger.info("core number of threads " + N_THREADS); 158 logger.info("current number of threads " + tpe.getPoolSize()); 159 logger.info("maximal number of threads " + tpe.getLargestPoolSize()); 160 BlockingQueue<Runnable> workpile = tpe.getQueue(); 161 if (workpile != null) { 162 logger.info("queued tasks " + workpile.size()); 163 } 164 List<Runnable> r = tpe.shutdownNow(); 165 if (r.size() != 0) { 166 logger.info("unfinished tasks " + r.size()); 167 } 168 logger.info("number of sheduled tasks " + tpe.getTaskCount()); 169 logger.info("number of completed tasks " + tpe.getCompletedTaskCount()); 170 } 171 pool = null; 172 //workpile = null; 173 } 174 175 176 /** 177 * Set no thread usage. 178 */ 179 public static synchronized void setNoThreads() { 180 NO_THREADS = true; 181 } 182 183 184 /** 185 * Set thread usage. 186 */ 187 public static synchronized void setThreads() { 188 NO_THREADS = false; 189 } 190 191 192 /** 193 * Set timeout. 194 * @param t time value to set 195 */ 196 public static synchronized void setTimeout(long t) { 197 timeout = t; 198 } 199 200 201 /** 202 * Get timeout. 203 * @return timeout value 204 */ 205 public static synchronized long getTimeout() { 206 return timeout; 207 } 208 209 210 /** 211 * Set TimeUnit. 212 * @param t TimeUnit value to set 213 */ 214 public static synchronized void setTimeUnit(TimeUnit t) { 215 timeunit = t; 216 } 217 218 219 /** 220 * Get TimeUnit. 221 * @return timeunit value 222 */ 223 public static synchronized TimeUnit getTimeUnit() { 224 return timeunit; 225 } 226 227}