差分
このページの2つのバージョン間の差分を表示します。
| 両方とも前のリビジョン前のリビジョン次のリビジョン | 前のリビジョン | ||
| study:java:threadpool [2011/08/03 04:08] – [Are We Done Yet?] banana | study:java:threadpool [2011/08/03 04:11] (現在) – [TestThreadPool.java] banana | ||
|---|---|---|---|
| 行 14: | 行 14: | ||
| ====== Are We Done Yet? ====== | ====== Are We Done Yet? ====== | ||
| - | thread pool이 task를 완료했는지 알려면 몇가지를 체크해야 한다. 첫째는 assignment array가 비어있어야 한다. | + | thread pool이 task를 완료했는지 알려면 몇가지를 체크해야 한다. 첫째는 assignment array가 비어있어야 한다. |
| 하지만 이것은 필요조건이지 충분조건은 아니다. 비어있다고 해도 pool안에는 실행되고 있는 %%WorkerThread%%가 존재할수도 있다.\\ | 하지만 이것은 필요조건이지 충분조건은 아니다. 비어있다고 해도 pool안에는 실행되고 있는 %%WorkerThread%%가 존재할수도 있다.\\ | ||
| thread pool이 작업완료 되었는지 검사하는 class가 %%Done.java%% 클래스이다. 하지만 사용할 때에는 직접 접근하지 않아도 된다.\\ 단지 task를 assign으로 할당하고 complete메소드를 부르기만 하면 된다. %%Done%% class는 두 메소드를 가지고 있다.\\ | thread pool이 작업완료 되었는지 검사하는 class가 %%Done.java%% 클래스이다. 하지만 사용할 때에는 직접 접근하지 않아도 된다.\\ 단지 task를 assign으로 할당하고 complete메소드를 부르기만 하면 된다. %%Done%% class는 두 메소드를 가지고 있다.\\ | ||
| %%WorkerThread%%가 시작될때 불리는 workerBegin메소드와 종료될 때 불리는 workerEnd메소드가 그것이다.\\ | %%WorkerThread%%가 시작될때 불리는 workerBegin메소드와 종료될 때 불리는 workerEnd메소드가 그것이다.\\ | ||
| 다음으로 thread pool example을 살펴본다. | 다음으로 thread pool example을 살펴본다. | ||
| + | |||
| + | ===== ThreadPool.java ===== | ||
| + | <code java> | ||
| + | package thread; | ||
| + | |||
| + | import java.util.ArrayList; | ||
| + | import java.util.Collection; | ||
| + | |||
| + | /** | ||
| + | * Java Thread Pool | ||
| + | | ||
| + | * This is a thread pool that for Java, it is | ||
| + | * simple to use and gets the job done. This program and | ||
| + | * all supporting files are distributed under the Limited | ||
| + | * GNU Public License (LGPL, http:// | ||
| + | | ||
| + | * This is the main class for the thread pool. You should | ||
| + | * create an instance of this class and assign tasks to it. | ||
| + | | ||
| + | * For more information visit http:// | ||
| + | | ||
| + | * @author Jeff Heaton (http:// | ||
| + | * @version 1.0 | ||
| + | */ | ||
| + | public class ThreadPool { | ||
| + | /** | ||
| + | * The threads in the pool. | ||
| + | */ | ||
| + | protected Thread threads[] = null; | ||
| + | /** | ||
| + | * The backlog of assignments, | ||
| + | * for the thread pool. | ||
| + | */ | ||
| + | Collection assignments = new ArrayList(3); | ||
| + | /** | ||
| + | * A Done object that is used to track when the | ||
| + | * thread pool is done, that is has no more work | ||
| + | * to perform. | ||
| + | */ | ||
| + | protected Done done = new Done(); | ||
| + | |||
| + | /** | ||
| + | * The constructor. | ||
| + | * | ||
| + | * @param size How many threads in the thread pool. | ||
| + | */ | ||
| + | public ThreadPool(int size) | ||
| + | { | ||
| + | threads = new WorkerThread[size]; | ||
| + | for (int i=0; | ||
| + | | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Add a task to the thread pool. Any class | ||
| + | * which implements the Runnable interface | ||
| + | * may be assienged. When this task runs, its | ||
| + | * run method will be called. | ||
| + | * | ||
| + | * @param r An object that implements the Runnable interface | ||
| + | */ | ||
| + | public synchronized void assign(Runnable r) | ||
| + | { | ||
| + | done.workerBegin(); | ||
| + | assignments.add(r); | ||
| + | notify(); | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Get a new work assignment. | ||
| + | * | ||
| + | * @return A new assignment | ||
| + | */ | ||
| + | public synchronized Runnable getAssignment() | ||
| + | { | ||
| + | try { | ||
| + | while ( !assignments.iterator().hasNext() ) | ||
| + | | ||
| + | |||
| + | | ||
| + | | ||
| + | | ||
| + | } catch (InterruptedException e) { | ||
| + | | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Called to block the current thread until | ||
| + | * the thread pool has no more work. | ||
| + | */ | ||
| + | public void complete() | ||
| + | { | ||
| + | done.waitBegin(); | ||
| + | done.waitDone(); | ||
| + | } | ||
| + | |||
| + | |||
| + | protected void finalize() | ||
| + | { | ||
| + | done.reset(); | ||
| + | for (int i=0; | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | done.waitDone(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== WorkerThread.java ===== | ||
| + | <code java> | ||
| + | package thread; | ||
| + | |||
| + | /** | ||
| + | * The worker threads that make up the thread pool. | ||
| + | | ||
| + | * @author Jeff Heaton | ||
| + | * @version 1.0 | ||
| + | */ | ||
| + | class WorkerThread extends Thread { | ||
| + | /** | ||
| + | * True if this thread is currently processing. | ||
| + | */ | ||
| + | public boolean busy; | ||
| + | /** | ||
| + | * The thread pool that this object belongs to. | ||
| + | */ | ||
| + | public ThreadPool owner; | ||
| + | |||
| + | /** | ||
| + | * The constructor. | ||
| + | * | ||
| + | * @param o the thread pool | ||
| + | */ | ||
| + | WorkerThread(ThreadPool o) | ||
| + | { | ||
| + | owner = o; | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Scan for and execute tasks. | ||
| + | */ | ||
| + | public void run() | ||
| + | { | ||
| + | Runnable target = null; | ||
| + | |||
| + | do { | ||
| + | | ||
| + | if (target!=null) { | ||
| + | target.run(); | ||
| + | owner.done.workerEnd(); | ||
| + | } | ||
| + | } while (target!=null); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | </ | ||
| + | |||
| + | ===== Done.java ===== | ||
| + | <code java> | ||
| + | package thread; | ||
| + | |||
| + | /** | ||
| + | | ||
| + | * This is a thread pool for Java, it is | ||
| + | * simple to use and gets the job done. This program and | ||
| + | * all supporting files are distributed under the Limited | ||
| + | * GNU Public License (LGPL, http:// | ||
| + | | ||
| + | * This is a very simple object that | ||
| + | * allows the TheadPool to determine when | ||
| + | * it is done. This object implements | ||
| + | * a simple lock that the ThreadPool class | ||
| + | * can wait on to determine completion. | ||
| + | * Done is defined as the ThreadPool having | ||
| + | * no more work to complete. | ||
| + | | ||
| + | * Copyright 2001 by Jeff Heaton | ||
| + | * | ||
| + | * @author Jeff Heaton (http:// | ||
| + | * @version 1.0 | ||
| + | */ | ||
| + | public class Done { | ||
| + | |||
| + | /** | ||
| + | * The number of Worker object | ||
| + | * threads that are currently working | ||
| + | * on something. | ||
| + | */ | ||
| + | private int _activeThreads = 0; | ||
| + | |||
| + | /** | ||
| + | * This boolean keeps track of if | ||
| + | * the very first thread has started | ||
| + | * or not. This prevents this object | ||
| + | * from falsely reporting that the ThreadPool | ||
| + | * is done, just because the first thread | ||
| + | * has not yet started. | ||
| + | */ | ||
| + | private boolean _started = false; | ||
| + | |||
| + | /** | ||
| + | * This method can be called to block | ||
| + | * the current thread until the ThreadPool | ||
| + | * is done. | ||
| + | */ | ||
| + | synchronized public void waitDone() | ||
| + | { | ||
| + | try { | ||
| + | while ( _activeThreads> | ||
| + | | ||
| + | } | ||
| + | } catch ( InterruptedException e ) { | ||
| + | } | ||
| + | } | ||
| + | /** | ||
| + | * Called to wait for the first thread to | ||
| + | * start. Once this method returns the | ||
| + | * process has begun. | ||
| + | */ | ||
| + | |||
| + | synchronized public void waitBegin() | ||
| + | { | ||
| + | try { | ||
| + | while ( !_started ) { | ||
| + | | ||
| + | } | ||
| + | } catch ( InterruptedException e ) { | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | /** | ||
| + | * Called by a Worker object | ||
| + | * to indicate that it has begun | ||
| + | * working on a workload. | ||
| + | */ | ||
| + | synchronized public void workerBegin() | ||
| + | { | ||
| + | _activeThreads++; | ||
| + | _started = true; | ||
| + | notify(); | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Called by a Worker object to | ||
| + | * indicate that it has completed a | ||
| + | * workload. | ||
| + | */ | ||
| + | synchronized public void workerEnd() | ||
| + | { | ||
| + | _activeThreads--; | ||
| + | notify(); | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Called to reset this object to | ||
| + | * its initial state. | ||
| + | */ | ||
| + | synchronized public void reset() | ||
| + | { | ||
| + | _activeThreads = 0; | ||
| + | } | ||
| + | |||
| + | } | ||
| + | |||
| + | </ | ||
| + | |||
| + | ===== TestWorkerThread.java ===== | ||
| + | <code java> | ||
| + | package thread; | ||
| + | |||
| + | /** | ||
| + | * This class shows an example worker thread that can | ||
| + | * be used with the thread pool. It demonstrates the main | ||
| + | * points that should be included in any worker thread. Use | ||
| + | * this as a starting point for your own threads. | ||
| + | | ||
| + | * @author Jeff Heaton (http:// | ||
| + | * @version 1.0 | ||
| + | */ | ||
| + | public class TestWorkerThread implements Runnable { | ||
| + | static private int count = 0; | ||
| + | private int taskNumber; | ||
| + | protected Done done; | ||
| + | |||
| + | /** | ||
| + | * | ||
| + | * @param done | ||
| + | */ | ||
| + | TestWorkerThread() | ||
| + | { | ||
| + | count++; | ||
| + | taskNumber = count; | ||
| + | } | ||
| + | |||
| + | public void run() | ||
| + | { | ||
| + | for (int i=0; | ||
| + | | ||
| + | try { | ||
| + | | ||
| + | } catch (InterruptedException e) { | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | </ | ||
| + | |||
| + | ===== TestThreadPool.java ===== | ||
| + | <code java> | ||
| + | package thread; | ||
| + | |||
| + | /** | ||
| + | * thread pool | ||
| + | | ||
| + | * @author Jeff Heaton (http:// | ||
| + | * @version 1.0 | ||
| + | */ | ||
| + | public class TestThreadPool { | ||
| + | /** | ||
| + | * | ||
| + | * | ||
| + | * @param args No arguments are used. | ||
| + | */ | ||
| + | public static void main(String args[]) | ||
| + | { | ||
| + | ThreadPool pool = new ThreadPool(10); | ||
| + | |||
| + | for (int i=1; | ||
| + | pool.assign(new TestWorkerThread()); | ||
| + | } | ||
| + | |||
| + | pool.complete(); | ||
| + | |||
| + | System.out.println(" | ||
| + | } | ||
| + | } | ||
| + | |||
| + | </ | ||
| + | |||
| + | ====== reference ====== | ||
| + | - [[http:// | ||
| + | |||