📄 taskthreadworker.java
字号:
package org.trinet.util.graphics.task;
import javax.swing.SwingUtilities;
/**
* Derived from the original 3rd version of SwingWorker from Sun
* (aka SwingWorker 3). Concrete subclasses must implement a
* "doTask()" method which is invoked in a dedicated "daemon" thread.
* The default priority of the daemon is Thread.NORMAL_PRIORITY.
* The user can set the thread name and group before starting the
* task thread
* @see AbstractMonitorableTask
*/
public abstract class TaskThreadWorker {
private Object value; // see getValue(), setValue()
private int threadPriority =
Thread.NORM_PRIORITY;
private ThreadVar threadVar;
private ThreadGroup threadGroup;
private String threadName;
/**
* Inner class maintains reference to current task thread
* under synchronization control.
*/
private static class ThreadVar {
private Thread thread;
ThreadVar(Thread t) { thread = t; }
synchronized Thread get() { return thread; }
synchronized void clear() { thread = null; }
}
/**
* Empty constructor does not initialize members.
* User must invoke <code>start()</code> method
* to start the daemon thread. Concrete subclassesm
* must implement the <code>doTask()</code> method
* invoked by the daemon thread to do the work.
*/
public TaskThreadWorker() { }
/**
* Returns the value produced by the task thread.
* @returns null object not yet built.
*/
protected synchronized Object getValue() {
return value;
}
/**
* Sets the value produced by task thread
*/
private synchronized void setValue(Object x) {
value = x;
}
/**
* Constructs the object value returned by the <code>get</code> method.
* This is the bread-and-butter method that does all the work.
* Concrete subclasses must implement the task work in this method.
*/
public abstract Object doTask();
/**
* Invoked on the event dispatching thread, not the task thread,
* after the <code>doTask()</code> method returns.
* Implementers can put GUI updates dependent on the task thread
* results in concrete subclass overrides of this method.
*/
public void finished() { }
/**
* Interrupts the task thread; forces the task thread to stop.
* Sets the thread reference to null.
*/
public void interrupt() {
if (threadVar == null) return; // convenience to avoid NullPointerException
Thread t = threadVar.get();
if (t != null) {
t.interrupt();
}
threadVar.clear();
}
/**
* Return the value created by the <code>doTask()</code> method.
* Returns null if either the task thread was not started or the
* thread was interrupted before a value was produced. NOTE
* method blocks the invoking thread until <code>doTask()</code>
* in the daemon task thread returns.
* @return the value created by the <code>doTask()</code> method
*/
public Object get() {
while (true) {
Thread t = threadVar.get();
if (t == null) {
return getValue();
}
try {
t.join(); // waits for task thread to complete, then loop back
}
catch (InterruptedException e) {
Thread.currentThread().interrupt(); // propagate
return null;
}
}
}
/**
* Starts the daemon worker thread task.
* @see #doTask()
*/
public void start() {
interrupt();
initThread();
Thread t = threadVar.get();
if (t != null) {
t.start();
}
}
/**
* Returns true if task thread isInterrupted().
*/
public boolean isInterrupted() {
if (threadVar == null) return false;
Thread t = threadVar.get();
return (t != null && t.isInterrupted());
}
/**
* Returns true if thread not null, isAlive() && ! isInterrupted().
*/
public boolean isProcessing() {
if (threadVar == null) return false;
Thread t = threadVar.get();
return (t != null && t.isAlive() && ! t.isInterrupted());
}
/**
* Sets the task thread base priority. Invoke before starting thread.
*/
public void setPriority(int priority) {
if (priority < Thread.MIN_PRIORITY ) threadPriority = Thread.MIN_PRIORITY;
else if ( priority > Thread.MAX_PRIORITY) threadPriority = Thread.MAX_PRIORITY;
else threadPriority = priority;
}
/**
* Sets thread group of task thread. Invoke before starting thread.
*/
public void setThreadGroup(ThreadGroup threadGroup) {
this.threadGroup = threadGroup;
// thread group dies if empty this.threadGroup.setDaemon(true);
}
/**
* Returns ThreadGroup of task thread.
*/
protected ThreadGroup getThreadGroup() {
return threadGroup;
}
/**
* Sets name of the task thread. Invoke before starting thread.
*/
public void setThreadName(String threadName) {
this.threadName = threadName;
}
/**
* Returns name of the task thread.
*/
public String getThreadName() {
return threadName;
}
/**
* Returns the current task thread object.
* @returns null thread has not been started or thread has already completed.
*/
protected Thread getThread() {
return (threadVar == null) ? null : threadVar.get();
}
/**
* Method initializes the attributes for a new task thread.
* Invoked by start() before starting task thread.
* @see #start()
*/
protected void initThread() {
final Runnable doFinished = new Runnable() {
public void run() { finished(); }
};
Runnable doConstruction = new Runnable() {
public void run() {
try {
setValue(doTask());
}
finally {
threadVar.clear();
}
SwingUtilities.invokeLater(doFinished);
}
};
Thread t = null;
if (threadName == null) {
t = new Thread(threadGroup, doConstruction);
}
else {
t = new Thread(threadGroup, doConstruction, threadName);
}
if (threadGroup == null) threadGroup = t.getThreadGroup();
if (threadName == null) threadName = t.getName();
//System.out.println(" group: "+t.getThreadGroup().getName()+" name: "+t.getName());
t.setPriority(threadPriority); // allows priority to be other than normal
t.setDaemon(true); // task thread dies, if all non-daemon die (e.g. main)
threadVar = new ThreadVar(t);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -