📄 threadpool.java
字号:
* * @param priority The priority to give to the threads in the pool. If * less than 'Thread.MIN_PRIORITY' it will be the same as the priority of * the calling thread. * * @param name The name of the pool. If null a default generic name is * chosen. * * @see NativeServices * * @see #CONCURRENCY_PROP_NAME * */ public ThreadPool(int size, int priority, String name) { int i; ThreadPoolThread t; String prop; int clevel; // Initialize variables checking for special cases if (size <= 0) { throw new IllegalArgumentException("Pool must be of positive size"); } if (priority < Thread.MIN_PRIORITY) { poolPriority = Thread.currentThread().getPriority(); } else { poolPriority = (priority < Thread.MAX_PRIORITY) ? priority : Thread.MAX_PRIORITY; } if (name == null) { poolName = "Anonymous ThreadPool"; } else { poolName = name; } // If requested to set concurrency try to do it prop = System.getProperty(CONCURRENCY_PROP_NAME); if (prop == null) { // No concurrency to set, do nothing } else { // Get concurrency level try { clevel = Integer.parseInt(prop); if (clevel < 0) throw new NumberFormatException(); } catch (NumberFormatException e) { throw new IllegalArgumentException("Invalid concurrency level "+ "in property "+ CONCURRENCY_PROP_NAME); } // Attempt to load library if (NativeServices.loadLibrary()) { // Library load successful FacilityManager.getMsgLogger(). printmsg(MsgLogger.INFO,"Changing thread concurrency "+ "level from "+ NativeServices.getThreadConcurrency()+ " to "+clevel+"."); NativeServices.setThreadConcurrency(clevel); } else { // Could not load the library => warn FacilityManager.getMsgLogger(). printmsg(MsgLogger.WARNING,"Native library to set "+ "thread concurrency level as specified by the "+ CONCURRENCY_PROP_NAME+" property not found. "+ "Thread concurrency unchanged."); } } // Allocate internal variables idle = new ThreadPoolThread[size]; nidle = 0; // Create and start the threads for (i=0; i<size; i++) { t = new ThreadPoolThread(i,poolName+"-"+i); t.start(); } } /** * Returns the size of the pool. That is the number of threads in this * pool (idle + busy). * * @return The pool's size. * * */ public int getSize() { return idle.length; } /** * Runs the run method of the specified target in an idle thread of this * pool. When the target's run method completes, the thread waiting on the * lock object is notified, if any. If there is currently no idle thread * the method will block until a thread of the pool becomes idle or the * calling thread is interrupted. * * <P>This method is the same as <tt>runTarget(t,l,true,false)</tt>. * * @param t The target. The 'run()' method of this object will be run in * an idle thread of the pool. * * @param l The lock object. A thread waiting on the lock of the 'l' * object will be notified, through the 'notify()' call, when the target's * run method completes. If null no thread is notified. * * @return True if the target was submitted to some thread. False if no * idle thread could be found and the target was not submitted for * execution. * * */ public boolean runTarget(Runnable t, Object l) { return runTarget(t,l,false,false); } /** * Runs the run method of the specified target in an idle thread of this * pool. When the target's run method completes, the thread waiting on the * lock object is notified, if any. If there is currently no idle thread * and the asynchronous mode is not used the method will block until a * thread of the pool becomes idle or the calling thread is * interrupted. If the asynchronous mode is used then the method will not * block and will return false. * * <P>This method is the same as <tt>runTarget(t,l,async,false)</tt>. * * @param t The target. The 'run()' method of this object will be run in * an idle thread of the pool. * * @param l The lock object. A thread waiting on the lock of the 'l' * object will be notified, through the 'notify()' call, when the target's * run method completes. If null no thread is notified. * * @param async If true the asynchronous mode will be used. * * @return True if the target was submitted to some thread. False if no * idle thread could be found and the target was not submitted for * execution. * * */ public boolean runTarget(Runnable t, Object l, boolean async) { return runTarget(t,l,async,false); } /** * Runs the run method of the specified target in an idle thread of this * pool. When the target's run method completes, the thread waiting on the * lock object is notified, if any. If there is currently no idle thread * and the asynchronous mode is not used the method will block until a * thread of the pool becomes idle or the calling thread is * interrupted. If the asynchronous mode is used then the method will not * block and will return false. * * @param t The target. The 'run()' method of this object will be run in * an idle thread of the pool. * * @param l The lock object. A thread waiting on the lock of the 'l' * object will be notified, through the 'notify()' call, when the target's * run method completes. If null no thread is notified. * * @param async If true the asynchronous mode will be used. * * @param notifyAll If true, threads waiting on the lock of the 'l' object * will be notified trough the 'notifyAll()' instead of the normal * 'notify()' call. This is not normally needed. * * @return True if the target was submitted to some thread. False if no * idle thread could be found and the target was not submitted for * execution. * * */ public boolean runTarget(Runnable t, Object l, boolean async, boolean notifyAll) { ThreadPoolThread runner; // The thread to run the target // Get a thread to run runner = getIdle(async); // If no runner return failure if (runner == null) return false; // Set the runner runner.setTarget(t,l,notifyAll); return true; } /** * Checks that no error or runtime exception in any target have occurred * so far. If an error or runtime exception has occurred in a target's run * method they are thrown by this method. * * @exception Error If an error condition has been thrown by a target * 'run()' method. * * @exception RuntimeException If a runtime exception has been thrown by a * target 'run()' method. * */ public void checkTargetErrors() { // Check for Error if (targetE != null) throw targetE; // Check for RuntimeException if (targetRE != null) throw targetRE; } /** * Clears the current target error conditions, if any. Note that a thread * in the pool might have set the error conditions since the last check * and that those error conditions will be lost. Likewise, before * returning from this method another thread might set the error * conditions. There is no guarantee that no error conditions exist when * returning from this method. * * <P>In order to ensure that no error conditions exist when returning * from this method cooperation from the targets and the thread using this * pool is necessary (i.e. currently no targets running or waiting to * run). * */ public void clearTargetErrors() { // Clear the error and runtime exception conditions targetE = null; targetRE = null; } /** * Puts the thread 't' in the idle list. The thread 't' should be in fact * idle and ready to accept a new target when it joins the idle list. * * <P> An idle thread that is already in the list should never add itself * to the list before it is removed. For efficiency reasons there is no * check to see if the thread is already in the list of idle threads. * * <P> If the idle list was empty 'notify()' will be called on the 'idle' * array, to wake up a thread that might be waiting (within the * 'getIdle()' method) on an idle thread to become available. * * @param t The thread to put in the idle list. * */ private void putInIdleList(ThreadPoolThread t) { // NOTE: if already in idle => catastrophe! (should be OK since // // this is private method) // Lock the idle array to avoid races with 'getIdle()' synchronized (idle) { idle[nidle] = t; nidle++; // If idle array was empty wakeup any waiting threads. if (nidle == 1) idle.notify(); } } /** * Returns and idle thread and removes it from the list of idle * threads. In asynchronous mode it will immediately return an idle * thread, or null if none is available. In non-asynchronous mode it will * block until a thread of the pool becomes idle or the calling thread is * interrupted. * * <P>If in non-asynchronous mode and there are currently no idle threads * available the calling thread will wait on the 'idle' array lock, until * notified by 'putInIdleList()' that an idle thread might have become * available. * * @param async If true asynchronous mode is used. * * @return An idle thread of the pool, that has been removed from the idle * list, or null if none is available. * */ private ThreadPoolThread getIdle(boolean async) { // Lock the idle array to avoid races with 'putInIdleList()' synchronized (idle) { if (async) { // In asynchronous mode just return null if no idle thread if (nidle == 0) return null; } else { // In synchronous mode wait until a thread becomes idle while (nidle == 0) { try { idle.wait(); } catch (InterruptedException e) { // If we were interrupted just return null return null; } } } // Decrease the idle count and return one of the idle threads nidle--; return idle[nidle]; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -