1   /* ====================================================================
2    * License: 
3    * 
4    * Redistribution and use in source and binary forms, with or without
5    * modification, are permitted provided that the following conditions
6    * are met:
7    *
8    * 1. Redistributions of source code must retain the above copyright
9    *    notice, this list of conditions and the following disclaimer.
10   *
11   * 2. Redistributions in binary form must reproduce the above copyright
12   *    notice, this list of conditions and the following disclaimer in
13   *    the documentation and/or other materials provided with the
14   *    distribution.
15   *
16   * 3. The end-user documentation included with the redistribution,
17   *    if any, must include the following acknowledgment:
18   *       "This product includes software developed by 
19   *        Robert Half International (http://www.rhi.com/)."
20   *    Alternately, this acknowledgment may appear in the software itself,
21   *    if and wherever such third-party acknowledgments normally appear.
22   *
23   * 4. The names "Parc", "RHI", and "Robert Half International" must
24   *    not be used to endorse or promote products derived from this
25   *    software without prior written permission. For written
26   *    permission, please contact pete.mckinstry@rhi.com.
27   *
28   * 5. Products derived from this software may not be called "PARC",
29   *    nor may "PARC" appear in their name, without prior written
30   *    permission of Robert Half International.
31   *
32   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
33   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
34   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
36   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
37   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
38   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
39   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
40   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
41   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
42   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43   * SUCH DAMAGE.
44   * ====================================================================
45   *
46   */
47  package com.rhi.architecture.threads;
48  
49  import java.util.ArrayList;
50  
51  /***
52   * Custom ThreadPool Implementation. The ThreadPool is started with predefined
53   * set of WorkerThreads which actually perform the work.
54   *
55   * This ThreadPool is suitable for scenarios work is split across
56   * mutiple threads and main thread waits for all the worker threads to
57   * finish and assigns work to all (or part) of worker threads.
58   *
59   * The ThreadPool can be asked to find a worked thread and assign work to it using
60   * execute method. Using join() method the caller will wait for all the worker
61   * threads to finish.
62   *
63   * IMPORTANT NOTE(S):
64   *
65   * 1. This ThreadPool is suitable for use by a single thread, not by mutliple
66   *    threads/requests    requesting ThreadPool to execute work.
67   * 2. It is the responsibility of the caller to make sure that it requests at
68   *    maximum 'poolsize' amount of work to be performed by the ThreadPool.
69   *    If no workers are free an RuntimeException is thrown. 
70   * 
71   * @author <a href="mailto:Chandra.Ilindra@rhi.com">Chandra Ilindra</a>
72   * @copyright 2002, Robert Half Int'l. All rights reserved.
73   *
74   * @version 1.0
75   */
76  public class ThreadPoolImpl implements ThreadPool {
77  
78     // maintain a pool of worker threads.
79     ArrayList pool = null;
80  
81     // pool size
82     int poolSize = 1;
83  
84     /***
85      * Constructor - constructs a ThreadPool of given size. Constructs
86      * returns after all the threads have been created and started.
87      *
88      * @param size - size of the pool
89      *
90      * @since 1.0
91      */
92     public ThreadPoolImpl(int size) {
93  
94        poolSize = size;
95        pool = new ArrayList(size);
96  
97        for (int i = 0; i < size; i++) {
98           WorkerThread wThread = new WorkerThread(this);
99           wThread.setName("WorkerThread_" + i);
100          wThread.start();
101          pool.add(wThread);
102       }
103 
104    }
105 
106    /***
107     * Executes a given 'work'. Finds a free worker thread to execute the
108     * work - sets the work and notifies the worked thread to wake up
109     * and perform the work.
110     *
111     * @param work - work to be performed.
112     * @throws RuntimeException
113     * @since 1.0
114     */
115    public void execute(Runnable work) throws RuntimeException {
116 
117       boolean allWorkersBusy = true;
118 
119       for (int i = 0; i < poolSize; i++) {
120          WorkerThread wThread = (WorkerThread) pool.get(i);
121          if (wThread.noWork()) {
122             wThread.setWork(work);
123             synchronized (wThread) {
124                wThread.notify();
125             }
126             allWorkersBusy = false;
127             break;
128          }
129       }
130 
131       if (allWorkersBusy) {
132          throw new RuntimeException("All Workers are busy could not perform the work.!");
133       }
134    }
135 
136    /***
137     * Wait for all the worker threads to finish. If there are workers still
138     * performing the work, sleep for a second and then check again.
139     *
140     * @since 1.0
141     */
142    public void join() {
143 
144       while (true) {
145          boolean allWorkersFree = true;
146          for (int i = 0; i < poolSize; i++) {
147             WorkerThread wThread = (WorkerThread) pool.get(i);
148             if (!wThread.noWork() && wThread.isAlive()) {
149                try {
150                   allWorkersFree = false;
151                   Thread.sleep(1000);
152                }
153                catch (InterruptedException e) {
154                   // ignore exception and continue.
155                }
156                break; // come out of worker thread loop.
157             }
158          }
159 
160          if (allWorkersFree) {
161             // enough of waiting, all finished, return.
162             break;
163          }
164       }
165 
166    }
167 
168    /***
169     * Mark all threads to shutdown and notify them, just in case they are
170     * sleeping.
171     *
172     * @since 1.0
173     */
174    public void close() {
175 
176       for (int i = 0; i < poolSize; i++) {
177          WorkerThread wThread = (WorkerThread) pool.get(i);
178          wThread.markForShutDown();
179          synchronized (wThread) {
180             wThread.notify();
181          }
182       }
183 
184    }
185 }
This page was automatically generated by Maven