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