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