KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > lobobrowser > util > SimpleThreadPool


1 package org.lobobrowser.util;
2
3 import java.util.*;
4 import java.util.logging.*;
5
6 /**
7  * A thread pool that allows cancelling all running tasks without
8  * shutting down the thread pool.
9  */

10 public class SimpleThreadPool {
11     private static final Logger logger = Logger.getLogger(SimpleThreadPool.class.getName());
12     private final LinkedList taskList = new LinkedList();
13     private final Set runningSet = new HashSet();
14     private final int minThreads;
15     private final int maxThreads;
16     private final String JavaDoc name;
17     private final int idleAliveMillis;
18     private final Object JavaDoc taskMonitor = new Object JavaDoc();
19     private int numThreads = 0;
20     private int numIdleThreads = 0;
21     private int threadNumber = 0;
22     
23     public SimpleThreadPool(String JavaDoc name, int minShrinkToThreads, int maxThreads, int idleAliveMillis) {
24         this.minThreads = minShrinkToThreads;
25         this.maxThreads = maxThreads;
26         this.idleAliveMillis = idleAliveMillis;
27         this.name = name;
28     }
29     
30     public void schedule(SimpleThreadPoolTask task) {
31         if(task == null) {
32             throw new IllegalArgumentException JavaDoc("null task");
33         }
34         Object JavaDoc monitor = this.taskMonitor;
35         synchronized(monitor) {
36             if(this.numIdleThreads == 0) {
37                 this.addThreadImpl();
38             }
39             this.taskList.add(task);
40             monitor.notify();
41         }
42     }
43     
44     public void cancel(SimpleThreadPoolTask task) {
45         synchronized(this.taskMonitor) {
46             this.taskList.remove(task);
47         }
48         task.cancel();
49     }
50     
51     private void addThreadImpl() {
52         if(this.numThreads < this.maxThreads) {
53             Thread JavaDoc t = new Thread JavaDoc(new ThreadRunnable(), this.name + this.threadNumber++);
54             t.setDaemon(true);
55             t.start();
56             this.numThreads++;
57         }
58     }
59
60     /**
61      * Cancels all waiting tasks and any currently running task.
62      */

63     public void cancelAll() {
64         synchronized(this.taskMonitor) {
65             this.taskList.clear();
66             Iterator i = this.runningSet.iterator();
67             while(i.hasNext()) {
68                 ((SimpleThreadPoolTask) i.next()).cancel();
69             }
70         }
71     }
72
73     private class ThreadRunnable implements Runnable JavaDoc {
74         public void run() {
75             Object JavaDoc monitor = taskMonitor;
76             LinkedList tl = taskList;
77             Set rs = runningSet;
78             int iam = idleAliveMillis;
79             SimpleThreadPoolTask task = null;
80             for(;;) {
81                 try {
82                     synchronized(monitor) {
83                         if(task != null) {
84                             rs.remove(task);
85                         }
86                         numIdleThreads++;
87                         try {
88                             long waitBase = System.currentTimeMillis();
89                             INNER:
90                             while(tl.isEmpty()) {
91                                 long maxWait = iam - (System.currentTimeMillis() - waitBase);
92                                 if(maxWait <= 0) {
93                                     if(numThreads > minThreads) {
94                                         // Should be only way to exit thread.
95
numThreads--;
96                                         return;
97                                     }
98                                     else {
99                                         waitBase = System.currentTimeMillis();
100                                         continue INNER;
101                                     }
102                                 }
103                                 monitor.wait(maxWait);
104                             }
105                         } finally {
106                             numIdleThreads--;
107                         }
108                         task = (SimpleThreadPoolTask) taskList.removeFirst();
109                         rs.add(task);
110                     }
111                     Thread JavaDoc currentThread = Thread.currentThread();
112                     String JavaDoc baseName = currentThread.getName();
113                     try {
114                         try {
115                             currentThread.setName(baseName + ":" + task.toString());
116                         } catch(Throwable JavaDoc thrown) {
117                             logger.log(Level.WARNING, "run(): Unable to set task name.", thrown);
118                         }
119                         try {
120                             task.run();
121                         } catch(Throwable JavaDoc thrown) {
122                             logger.log(Level.SEVERE, "run(): Error in task: " + task + ".", thrown);
123                         }
124                     } finally {
125                         currentThread.setName(baseName);
126                     }
127                 } catch(Throwable JavaDoc thrown) {
128                     logger.log(Level.SEVERE, "run(): Error in thread pool: " + SimpleThreadPool.this.name + ".", thrown);
129                 }
130             }
131         }
132     }
133 }
134
Popular Tags