如果使用Executor实现SwingUtilities
public class SwingUtilities{
private static final ExecutorService exec=
Executors.newSingleThreadExecutor(new SwingThreadFactory());
private static volatile Thread swingThread;
private static class SwingThreadFactory implements ThreadFactory{
public Thread newThread(Runnable r){
swingThread=new Thread(r);
return swingThread;
}
}
public static booleawn isEventDispatchThread(){
return Thread.currentThread()==swingThread;
}
public static void invokeLate(Runnable task){
exec.execute(task);
}
public static void invokeAndWait(Runnable task)throws InterruptException,InvocationTargetException{
Future f=exec.submit(task);
try{
f.get();
}catch(ExecutionException e){
throw new InvocationTargetException(e);
}
}
}
实际上SwingUtilities 并不是这样实现的。
public class GuiExecutor extends AbstractExecutorService{
private static final GuiExecutor instance=new GuiExecutor();
private GuiExecutor(){}
public static GuiExecutor instance(){
return instance;
}
public void execute(Runnable r){
if(SwingUtilities.isEventDispatchThread()){
r.run();
}else{
SwingUtilities.invokeLater(r);
}
}
}
鼠标点击—>action 事件—>action 监听器—> 更新 table 模型—>table 变化事件—>table 监听器—> 更新 table 视图
button.addActionListener(new ActionListerner(){
public void actionPerformed(ActionEvent e){
button.setEnable(false);
label.setText(“busy”);
backgroundExec.execute(new Runnable(){
public void run(){
try{
doBigComputation();
}finally{
GuiExecutor.instance().execute(new Runnable(){
public void run(){
button.setEnable(true);
label.setText(“idle”);
}
}
);
}
}
});
}
});
取消耗时的任务
Future<?> runningTask=null;
startButton.addActionListener(new ActionListener(){
public void actionPerforme(ActionEvent e){
if(runningTask==null){
runningTask=backgroundExec.submit(new Runnable(){
public void run(){
while(moreWork()){
if(Thread.interrupted()){
cleanUpPartialWork();
break;
}
doSomeWork();
}
}
});
}
}
});
cancelButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
if(runningTask!=null){
runningTask.cancel(true);
}
}
});
因为 runningTask 被限制在事件线程中,因此设置或检查他的时候不需要同步。
abstract class BackgroundTask<V> implements Runnable,Futuer<V>{
private final FutureTask<V> computation=new Computation();
private class Computation extends FutureTask<V>{
public Computation(){
super(new Callable<V>(){
public V call()throws Exception{}
return BackgroundTask.this.compute();
});
}
protected final void done(){
GuiExecutor.instance().execute(new Runnable(){
public void run(){
V value=null;
Throwable thrown=null;
boolean cancelled=false;
try{
value=get();
}catch(ExecutionException e){
thrown=e.getCause();
}catch(CancellationException e){
cancelled=true;
}catch(InterruptedException consumed){
}finally{
onCompletion(value,thrown,cancelled);
}
}
});
}
}
protected void setProgress(final int current,final int max){
GuiExecutor.instance.execute(new Runnable(){
public void run(){
onProgress(current,max);
}
});
}
protected abstract V compute() throws Exception;
protected void onCompletion(V result,Throwable exception,
boolean cancelled){}
protected void onProgress(int current,int max){}
}
支持取消、完成和进度通知的后台任务类
startButton.addActionListener(new ActionListener(
public void actionPerformed(ActionEvent e){
class CancelListener implements ActionListener{
BcakgroundTask<?> task;
public void actionPerformed(ActionEvent event){
if(task!=null){
task.cancel(true);
}
}
}
final CancelListener listener=new CancelListener();
listener.task=new BackgroundTask<Void>(){
public Void compute(){
while(moreWork()&&!isCancelled){
doSomeWork();
}
return null;
}
public void onCompletion(boolean cancelled,String s,Throwable exception){
cancelButton.removeActionListener(listener);
label.setText(“done”);
}
}
cancelButton.addActionListener(listener);
backgroundExec.execute(listener.task);
}
));