871 |
|
Thread.interrupted() && |
872 |
|
runState >= STOP) |
873 |
|
thread.interrupt(); |
874 |
< |
/* |
875 |
< |
* Track execution state to ensure that afterExecute |
876 |
< |
* is called only if task completed or threw |
877 |
< |
* exception. Otherwise, the caught runtime exception |
878 |
< |
* will have been thrown by afterExecute itself, in |
879 |
< |
* which case we don't want to call it again. |
880 |
< |
*/ |
881 |
< |
boolean ran = false; |
874 |
> |
|
875 |
|
beforeExecute(thread, task); |
876 |
+ |
Throwable ex = null; |
877 |
|
try { |
878 |
|
task.run(); |
879 |
< |
ran = true; |
880 |
< |
afterExecute(task, null); |
879 |
> |
} catch (Throwable throwable) { |
880 |
> |
ex = throwable; |
881 |
> |
} finally { |
882 |
|
++completedTasks; |
883 |
< |
} catch (RuntimeException ex) { |
889 |
< |
if (!ran) |
890 |
< |
afterExecute(task, ex); |
891 |
< |
throw ex; |
883 |
> |
afterExecute(task, ex); |
884 |
|
} |
885 |
|
} finally { |
886 |
|
runLock.unlock(); |
997 |
|
try { |
998 |
|
completedTaskCount += w.completedTasks; |
999 |
|
workers.remove(w); |
1000 |
< |
if (--poolSize == 0) |
1001 |
< |
tryTerminate(); |
1000 |
> |
--poolSize; |
1001 |
> |
tryTerminate(); |
1002 |
|
} finally { |
1003 |
|
mainLock.unlock(); |
1004 |
|
} |
1009 |
|
/** |
1010 |
|
* Transitions to TERMINATED state if either (SHUTDOWN and pool |
1011 |
|
* and queue empty) or (STOP and pool empty), otherwise unless |
1012 |
< |
* stopped, ensuring that there is at least one live thread to |
1013 |
< |
* handle queued tasks. |
1012 |
> |
* stopped, adding a thread if there are fewer than max(1, |
1013 |
> |
* corePoolSize) existing threads to handle queued tasks. |
1014 |
|
* |
1015 |
|
* This method is called from the three places in which |
1016 |
|
* termination can occur: in workerDone on exit of the last thread |
1018 |
|
* shutdown or shutdownNow, if there are no live threads. |
1019 |
|
*/ |
1020 |
|
private void tryTerminate() { |
1021 |
< |
if (poolSize == 0) { |
1021 |
> |
int n = poolSize; |
1022 |
> |
if (n < Math.max(1, corePoolSize)) { |
1023 |
|
int state = runState; |
1024 |
|
if (state < STOP && !workQueue.isEmpty()) { |
1032 |
– |
state = RUNNING; // disable termination check below |
1025 |
|
Thread t = addThread(null); |
1026 |
|
if (t != null) |
1027 |
|
t.start(); |
1028 |
+ |
return; |
1029 |
|
} |
1030 |
< |
if (state == STOP || state == SHUTDOWN) { |
1030 |
> |
if (n == 0 && (state == STOP || state == SHUTDOWN)) { |
1031 |
|
runState = TERMINATED; |
1032 |
|
termination.signalAll(); |
1033 |
|
terminated(); |
1612 |
|
* Returns the approximate total number of tasks that have ever been |
1613 |
|
* scheduled for execution. Because the states of tasks and |
1614 |
|
* threads may change dynamically during computation, the returned |
1615 |
< |
* value is only an approximation, but one that does not ever |
1623 |
< |
* decrease across successive calls. |
1615 |
> |
* value is only an approximation. |
1616 |
|
* |
1617 |
|
* @return the number of tasks |
1618 |
|
*/ |