001: package org.methodize.nntprss.util;
002:
003: /* -----------------------------------------------------------
004: * nntp//rss - a bridge between the RSS world and NNTP clients
005: * Copyright (c) 2002, 2003 Jason Brome. All Rights Reserved.
006: *
007: * email: nntprss@methodize.org
008: * mail: Methodize Solutions
009: * PO Box 3865
010: * Grand Central Station
011: * New York NY 10163
012: *
013: * This file is part of nntp//rss
014: *
015: * nntp//rss is free software; you can redistribute it
016: * and/or modify it under the terms of the GNU General
017: * Public License as published by the Free Software Foundation;
018: * either version 2 of the License, or (at your option) any
019: * later version.
020: *
021: * This program is distributed in the hope that it will be
022: * useful, but WITHOUT ANY WARRANTY; without even the implied
023: * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
024: * PURPOSE. See the GNU General Public License for more
025: * details.
026: *
027: * You should have received a copy of the GNU General Public
028: * License along with this program; if not, write to the
029: * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
030: * Boston, MA 02111-1307 USA
031: * ----------------------------------------------------- */
032:
033: import java.util.List;
034: import java.util.ArrayList;
035:
036: import org.apache.log4j.Logger;
037: import org.apache.log4j.Priority;
038:
039: /**
040: * @author Jason Brome <jason@methodize.org>
041: * @version $Id: FixedThreadPool.java,v 1.4 2003/03/08 19:48:53 jasonbrome Exp $
042: */
043:
044: public class FixedThreadPool {
045:
046: private ThreadGroup threadGroup = null;
047: private List pool = new ArrayList();
048: private boolean shutdown = false;
049: private String threadName;
050:
051: private Logger log = Logger.getLogger(FixedThreadPool.class);
052:
053: private class WorkerThread extends Thread {
054: private boolean shutdown = false;
055: private Runnable task;
056:
057: public WorkerThread(ThreadGroup threadGroup, String threadName) {
058: super (threadGroup, (Runnable) null, threadName);
059: }
060:
061: public void kill() {
062: shutdown = true;
063: interrupt();
064: }
065:
066: public void run(Runnable runnable) {
067: task = runnable;
068: synchronized (this ) {
069: notifyAll();
070: }
071: }
072:
073: public void run() {
074: while (!shutdown) {
075:
076: while (task == null) {
077: try {
078: synchronized (this ) {
079: wait();
080: }
081: } catch (InterruptedException ex) {
082: if (shutdown) {
083: return;
084: }
085: }
086: }
087:
088: try {
089: task.run();
090: } catch (Exception e) {
091: if (log.isEnabledFor(Priority.WARN)) {
092: log
093: .warn(
094: "Exception thrown in FixedThreadPool.Worker during task execution",
095: e);
096: }
097: }
098:
099: task = null;
100: if (shutdown) {
101: return;
102: }
103:
104: synchronized (pool) {
105: pool.add(this );
106: pool.notifyAll();
107: }
108: }
109: }
110: }
111:
112: // Constructor
113:
114: public FixedThreadPool(String name, String threadName,
115: int maxThreads) {
116: // Thread groups enable easier debugging in certain IDE,
117: // so lets assign our pool threads to a specific group
118:
119: if (name != null) {
120: threadGroup = new ThreadGroup(name);
121: } else {
122: threadGroup = new ThreadGroup("anonymous");
123: }
124:
125: if (threadName != null) {
126: this .threadName = threadName;
127: } else {
128: this .threadName = "STP-anonymous";
129: }
130:
131: for (int i = 0; i < maxThreads; i++) {
132: WorkerThread worker = new WorkerThread(threadGroup,
133: threadName + " #" + i);
134: pool.add(worker);
135: worker.start();
136: }
137: }
138:
139: public void shutdown() {
140: shutdown = true;
141: Object[] workers = pool.toArray();
142: for (int i = 0; i < workers.length; i++) {
143: ((WorkerThread) workers[i]).kill();
144: }
145:
146: synchronized (pool) {
147: pool.clear();
148: pool.notifyAll();
149: }
150: }
151:
152: public void run(Runnable task) {
153: WorkerThread worker = null;
154: synchronized (pool) {
155: while (pool.isEmpty()) {
156:
157: if (shutdown) {
158: return;
159: }
160: try {
161: pool.wait();
162: } catch (InterruptedException ex) {
163: return;
164: }
165: }
166:
167: worker = (WorkerThread) pool.remove(0);
168: }
169: worker.run(task);
170: }
171: }
|