/// <summary>Constructor.</summary> /// <param name="numThreads"> /// -- if less than or equal to 0, then automatically determine the number /// of threads. Otherwise, the size of the underlying threadpool. /// </param> /// <param name="processor"/> /// <param name="orderResults"> /// -- If true, return results in the order submitted. Otherwise, return results /// as they become available. /// </param> public MulticoreWrapper(int numThreads, IThreadsafeProcessor <I, O> processor, bool orderResults) { // Which id was the last id returned. Only meaningful in the case // of a queue where output order matters. // private final ExecutorCompletionService<Integer> queue; nThreads = numThreads <= 0 ? Runtime.GetRuntime().AvailableProcessors() : numThreads; this.orderResults = orderResults; outputQueue = new ConcurrentHashMap <int, O>(2 * nThreads); threadPool = BuildThreadPool(nThreads); // queue = new ExecutorCompletionService<Integer>(threadPool); idleProcessors = new ArrayBlockingQueue <int>(nThreads, false); callback = null; // Sanity check: Fixed thread pool so prevent timeouts. // Default should be false threadPool.AllowCoreThreadTimeOut(false); threadPool.PrestartAllCoreThreads(); // Setup the processors, one per thread IList <IThreadsafeProcessor <I, O> > procList = new List <IThreadsafeProcessor <I, O> >(nThreads); procList.Add(processor); idleProcessors.Add(0); for (int i = 1; i < nThreads; ++i) { procList.Add(processor.NewInstance()); idleProcessors.Add(i); } processorList = Java.Util.Collections.UnmodifiableList(procList); }
/// <exception cref="System.Exception"/> private void SubmitRefillTask(string keyName, Queue <E> keyQueue) { if (!executorThreadsStarted) { lock (this) { if (!executorThreadsStarted) { // To ensure all requests are first queued, make coreThreads = // maxThreads // and pre-start all the Core Threads. executor.PrestartAllCoreThreads(); executorThreadsStarted = true; } } } // The submit/execute method of the ThreadPoolExecutor is bypassed and // the Runnable is directly put in the backing BlockingQueue so that we // can control exactly how the runnable is inserted into the queue. queue.Put(new _NamedRunnable_324(this, keyQueue, keyName)); }