1484 | * Tasks start execution in the order they are received. 1485 | * 1486 | * @param task 1487 | * The task to run. If null, no action is taken. 1488 | * @throws IllegalStateException 1489 | * if this ThreadPool is already closed. 1490 | */ 1491 | public synchronized void runTask(Runnable task) { 1492 | if (!isAlive) { 1493 | throw new IllegalStateException(); 1494 | } 1495 | if (task != null) { 1496 | taskQueue.add(task); 1497 | notify(); 1498 | } 1499 | 1500 | } 1501 | 1502 | protected synchronized Runnable getTask() throws InterruptedException { 1503 | while (taskQueue.size() == 0) { 1504 | if (!isAlive) { 1505 | return null; 1506 | } 1507 | wait(); 1508 | } 1509 | return (Runnable) taskQueue.removeFirst(); 1510 | } 1511 | 1512 | /** 1513 | * Closes this ThreadPool and returns immediately. All threads are stopped, 1514 | * and any waiting tasks are not executed. Once a ThreadPool is closed, no 1515 | * more tasks can be run on this ThreadPool. 1516 | */ 1517 | public synchronized void close() { 1518 | if (isAlive) { 1519 | isAlive = false; 1520 | taskQueue.clear(); 1521 | interrupt(); 1522 | } 1523 | } 1524 | 1525 | /** 1526 | * Closes this ThreadPool and waits for all running threads to finish. Any 1527 | * waiting tasks are executed. 1528 | */ 1529 | public void join() { 1530 | // notify all waiting threads that this ThreadPool is no 1531 | // longer alive 1532 | synchronized (this) { 1533 | isAlive = false; 1534 | notifyAll(); 1535 | } 1536 | 1537 | // wait for all threads to finish 1538 | Thread[] threads = new Thread[activeCount()]; 1539 | int count = enumerate(threads); 1540 | for (int i = 0; i < count; i++) { 1541 | try { 1542 | threads[i].join(); 1543 | } catch (InterruptedException ex) { 1544 | } 1545 | } 1546 | } 1547 | 1548 | /** 1549 | * A PooledThread is a Thread in a ThreadPool group, designed to run tasks 1550 | * (Runnables). 1551 | */ 1552 | private class PooledThread extends Thread { 1553 | 1554 | public PooledThread() { 1555 | super(ThreadPool.this, "PooledThread-" + (threadID++)); 1556 | } 1557 | 1558 | public void run() { 1559 | while (!isInterrupted()) { 1560 | 1561 | // get a task to run 1562 | Runnable task = null; 1563 | try { 1564 | task = getTask(); 1565 | } catch (InterruptedException ex) { 1566 | } 1567 | 1568 | // if getTask() returned null or was interrupted, 1569 | // close this thread by returning. 1570 | if (task == null) { 1571 | return; 1572 | } 1573 | 1574 | // run the task, and eat any exceptions it throws 1575 | try { 1576 | task.run(); 1577 | } catch (Throwable t) { 1578 | uncaughtException(this, t); 1579 | } 1580 | } 1581 | } 1582 | } 1583 | } 1584 | } 1585 | --------------------------------------------------------------------------------