001: /*
002: * BEGIN_HEADER - DO NOT EDIT
003: *
004: * The contents of this file are subject to the terms
005: * of the Common Development and Distribution License
006: * (the "License"). You may not use this file except
007: * in compliance with the License.
008: *
009: * You can obtain a copy of the license at
010: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
011: * See the License for the specific language governing
012: * permissions and limitations under the License.
013: *
014: * When distributing Covered Code, include this CDDL
015: * HEADER in each file and include the License file at
016: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
017: * If applicable add the following below this CDDL HEADER,
018: * with the fields enclosed by brackets "[]" replaced with
019: * your own identifying information: Portions Copyright
020: * [year] [name of copyright owner]
021: */
022:
023: /*
024: * @(#)WorkThread.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: package com.sun.jbi.binding.jms.framework;
030:
031: import java.util.logging.Logger;
032:
033: /**
034: * This class executes the command in its thread. The class is always a part of
035: * a threadpool and cannot exist on its own.
036: *
037: * @author Sun Microsystems, Inc.
038: */
039: class WorkThread implements Runnable {
040: /**
041: * Default Thread sleep time in milliseconds.
042: */
043: private static final int DEFAULT_THREAD_SLEEP_TIME = 100;
044:
045: /**
046: * Thread sleep time in milliseconds.
047: */
048: private static int sThreadSleeptime = DEFAULT_THREAD_SLEEP_TIME;
049:
050: /**
051: * Container for holding the command to be executed in this thread.
052: */
053: private Command mCurrentCommand;
054:
055: /**
056: * Internal handle to the logger instance.
057: */
058: private Logger mLog;
059:
060: /**
061: * Flag to hold the state of the Thread. Valid states are "INIT", "READY",
062: * "PROCESS" and "STOP"
063: */
064: private String mState;
065:
066: /**
067: * Internal handle to the thread in which this runnable object is running.
068: */
069: private Thread mThread;
070:
071: /**
072: * Internal handle to WorkThreadPool.
073: */
074: private WorkThreadPool mThreadPool;
075:
076: /**
077: * A flag which indicates whether the thread should continue processing or
078: * not.
079: */
080: private boolean mContinue;
081:
082: /**
083: * Creates a new instance of WorkThread.
084: *
085: * @param workThreadPool - worker thread pool parent
086: */
087: WorkThread(WorkThreadPool workThreadPool) {
088: mThreadPool = workThreadPool;
089: mLog = Logger.getLogger(this .getClass().getPackage().getName());
090: setState("INIT");
091: }
092:
093: /**
094: * Sets the log file.
095: *
096: * @param logFile log file.
097: */
098: public void setLogger(String logFile) {
099: mLog = mLog.getLogger(logFile);
100: }
101:
102: /**
103: * Gets the thread name
104: *
105: * @return thread name.
106: */
107: public String getName() {
108: return mThread.getName();
109: }
110:
111: /**
112: * Sets the sleep time for the thread.
113: *
114: * @param time in millieseconds
115: */
116: public void setSleepTime(int time) {
117: sThreadSleeptime = time;
118: }
119:
120: /**
121: * The method polls the container for a new work when the thread is ready
122: * to do work. This is indicated by the method doWork(). If there is new
123: * work, it processes the command in its thread. Once the command has been
124: * processed, it clears its work container and notifies the thread pool
125: * that it is now free. The method will clean up the thread and shut
126: * itself down when its state is set to "STOP".
127: */
128: public void run() {
129: mThread = Thread.currentThread();
130: mLog.info("Running thread " + mThread.getName());
131: mContinue = true;
132:
133: while (mContinue) {
134: if (isWorkAssigned()) {
135: try {
136: processCommand();
137: } catch (Throwable th) {
138: mLog.info("The command failed to execute");
139: th.printStackTrace();
140: }
141:
142: clearCommand();
143: mThreadPool.releaseThread(this );
144: }
145:
146: try {
147: Thread.sleep(sThreadSleeptime);
148: } catch (InterruptedException interruptException) {
149: // someone must have interrupted this thread
150: // do nothing
151: mLog.info("Received an interrupt signal in "
152: + mThread.getName());
153: }
154: }
155:
156: try {
157: mLog.info("Thread " + mThread.getName()
158: + " has been stopped");
159: } catch (Exception e) {
160: ;
161: }
162: }
163:
164: /**
165: * Assigns the command to this thread.
166: *
167: * @param command - command instance.
168: */
169: synchronized void setCommand(Command command) {
170: if (mCurrentCommand == null) {
171: mCurrentCommand = command;
172: }
173: }
174:
175: /**
176: * Gets the command associated with this thread.
177: *
178: * @return the command associated with the thread
179: */
180: synchronized Command getCommand() {
181: return mCurrentCommand;
182: }
183:
184: /**
185: * Sets the State of the Worker Thread.
186: *
187: * @param state - worker thread state.
188: */
189: void setState(String state) {
190: mState = state;
191: }
192:
193: /**
194: * Returns a boolean indicating if work has been assigned to this thread.
195: *
196: * @return true if work has been allocated to this thread; otherwise false.
197: */
198: synchronized boolean isWorkAssigned() {
199: return (mCurrentCommand != null);
200: }
201:
202: /**
203: * Clears the command associated with the thread.
204: */
205: void clearCommand() {
206: mCurrentCommand = null;
207: }
208:
209: /**
210: * Processes the command in this thread.
211: */
212: void processCommand() {
213: mCurrentCommand.execute();
214: }
215:
216: /**
217: * Stops the worker thread.
218: *
219: * @throws IllegalStateException
220: */
221: void stop() {
222: if (mContinue) {
223: mLog.fine("Shutting down thread " + getName());
224: mContinue = false;
225:
226: try {
227: // Interrupt the thread so that it can shutdown quickly
228: // This will also enable the command implementation to cleanup quickly.
229: mThread.interrupt();
230: } catch (SecurityException securityException) {
231: mLog.warning("Could not interrupt thread");
232: mLog.warning("Details : "
233: + securityException.toString());
234: }
235:
236: try {
237: //Wait for the thread to stop
238: mThread.join();
239: } catch (InterruptedException exp) {
240: ; // do nothing
241: }
242:
243: mThread = null;
244: } else {
245: throw new IllegalStateException("Thread is not running");
246: }
247: }
248: }
|