797 |
|
* been completed. Thus, a worker thread may be interrupted |
798 |
|
* needlessly (for example in getTask), in which case it rechecks |
799 |
|
* pool state to see if it should exit. |
800 |
– |
* |
800 |
|
*/ |
801 |
|
private final class Worker implements Runnable { |
802 |
|
/** |
919 |
|
* approach is similar to execute() in that worker threads trying |
920 |
|
* to get a task to run do so on the basis of prevailing state |
921 |
|
* accessed outside of locks. This may cause them to choose the |
922 |
< |
* "wrong" action, such as or trying to exit because no tasks |
922 |
> |
* "wrong" action, such as trying to exit because no tasks |
923 |
|
* appear to be available, or entering a take when the pool is in |
924 |
< |
* the process of being shut down. These potential problems are |
924 |
> |
* the process of being shut down. These potential problems are |
925 |
|
* countered by (1) rechecking pool state (in workerCanExit) |
926 |
|
* before giving up, and (2) interrupting other workers upon |
927 |
|
* shutdown, so they can recheck state. All other user-based state |
1060 |
|
* threads that might be blocked in getTask() to wake them up |
1061 |
|
* so they can exit. Then, if there happen not to be any |
1062 |
|
* threads or tasks, we can directly terminate pool via |
1063 |
< |
* tryTerminate. |
1063 |
> |
* tryTerminate. Else, the last worker to leave the building |
1064 |
> |
* turns off the lights (in workerDone). |
1065 |
|
* |
1066 |
|
* But this is made more delicate because we must cooperate |
1067 |
|
* with the security manager (if present), which may implement |
1082 |
|
* SecurityException when interrupt() is invoked. In this |
1083 |
|
* third case, because we have already set runState, we can |
1084 |
|
* only try to back out from the shutdown as cleanly as |
1085 |
< |
* possible. Some threads may have been killed but we remain |
1086 |
< |
* in non-shutdown state (which may entail tryTerminate |
1087 |
< |
* starting a thread to maintain liveness.) |
1085 |
> |
* possible. Some workers may have been killed but we remain |
1086 |
> |
* in non-shutdown state (which may entail tryTerminate from |
1087 |
> |
* workerDone starting a new worker to maintain liveness.) |
1088 |
|
*/ |
1089 |
|
|
1090 |
|
SecurityManager security = System.getSecurityManager(); |
1095 |
|
mainLock.lock(); |
1096 |
|
try { |
1097 |
|
if (security != null) { // Check if caller can modify our threads |
1098 |
< |
for (Worker w: workers) |
1098 |
> |
for (Worker w : workers) |
1099 |
|
security.checkAccess(w.thread); |
1100 |
|
} |
1101 |
|
|
1104 |
|
runState = SHUTDOWN; |
1105 |
|
|
1106 |
|
try { |
1107 |
< |
for (Worker w: workers) { |
1107 |
> |
for (Worker w : workers) { |
1108 |
|
w.interruptIfIdle(); |
1109 |
|
} |
1110 |
|
} catch (SecurityException se) { // Try to back out |
1111 |
|
runState = state; |
1112 |
< |
tryTerminate(); |
1112 |
> |
// tryTerminate() here would be a no-op |
1113 |
|
throw se; |
1114 |
|
} |
1115 |
|
|
1140 |
|
public List<Runnable> shutdownNow() { |
1141 |
|
/* |
1142 |
|
* shutdownNow differs from shutdown only in that |
1143 |
< |
* (1) runState is set to STOP, (2) All worker threads |
1144 |
< |
* are interrupted, not just the idle ones, and (3) |
1145 |
< |
* the queue is drained and returned. |
1143 |
> |
* 1. runState is set to STOP, |
1144 |
> |
* 2. all worker threads are interrupted, not just the idle ones, and |
1145 |
> |
* 3. the queue is drained and returned. |
1146 |
|
*/ |
1147 |
|
SecurityManager security = System.getSecurityManager(); |
1148 |
|
if (security != null) |
1152 |
|
mainLock.lock(); |
1153 |
|
try { |
1154 |
|
if (security != null) { // Check if caller can modify our threads |
1155 |
< |
for (Worker w: workers) |
1155 |
> |
for (Worker w : workers) |
1156 |
|
security.checkAccess(w.thread); |
1157 |
|
} |
1158 |
|
|
1166 |
|
} |
1167 |
|
} catch (SecurityException se) { // Try to back out |
1168 |
|
runState = state; |
1169 |
< |
tryTerminate(); |
1169 |
> |
// tryTerminate() here would be a no-op |
1170 |
|
throw se; |
1171 |
|
} |
1172 |
|
|
1182 |
|
* Drains the task queue into a new list. Used by shutdownNow. |
1183 |
|
* Call only while holding main lock. |
1184 |
|
*/ |
1185 |
< |
private List<Runnable> drainQueue() { |
1185 |
> |
private List<Runnable> drainQueue() { |
1186 |
|
List<Runnable> taskList = new ArrayList<Runnable>(); |
1187 |
|
workQueue.drainTo(taskList); |
1188 |
|
/* |
1479 |
|
* terminated. This overrides any value set in the constructor. |
1480 |
|
* @param time the time to wait. A time value of zero will cause |
1481 |
|
* excess threads to terminate immediately after executing tasks. |
1482 |
< |
* @param unit the time unit of the time argument |
1482 |
> |
* @param unit the time unit of the time argument |
1483 |
|
* @throws IllegalArgumentException if time less than zero or |
1484 |
|
* if time is zero and allowsCoreThreadTimeOut |
1485 |
|
* @see #getKeepAliveTime |