代码改变世界

Java 客户端界面功能:停止当前操作

2013-12-16 09:57  _cha1R  阅读(416)  评论(0编辑  收藏  举报

在我们用JAVA做客户端的时候,可能会遇上这么一个需求:停止当前正在执行的一个操作。

这个操作或者操作时间过长而让客户不想等待它,从而要停止它的执行。那这个操作怎么做呢?

我们都知道,我们在使用事件触发来执行一个业务方法,一般需要使用一个新的线程,否者当前的UI线程会卡死,以Swing为例,JButton被点击后触发事件的代码:

                btn.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                //执行业务方法
                                System.out.println("执行。这个方法要执行很久!!");
                            }
                        }).start();
                    }
                });

那么我们要取消执行这个方法,最好最直接的做法就是停掉它。

所以我们要想一个办法来管理这些线程,在这里我没有使用线程池来管理,而是适用一个List来管理。

    private static LinkedList<Thread> threadList = new LinkedList<Thread>();
    public static LinkedList<Thread> getThreadList() {
        return threadList;
    }

为什么要用LinkedList?因为它可以快速的找到头尾元素,从而提高性能。这里List我用它来装着每一个由UI启动的执行业务方法的线程。

            loginBtn.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent evt) {
                    Thread thread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            System.out.println("登陆。。这个方法要执行5秒");
                        }
                    });
                    thread.start();    //开始执行
                    threadList.add(thread);    //把线程放到List里
                }
            });

既然把线程放在了List里,那要停止它很简单,把它找到,然后调用stop()方法:

private void stopBtnActionPerformed(ActionEvent e) {
        Thread thread = null;
        try{
            thread = threadList.getLast();
            thread.stop();
            System.out.println("操作被已手动停止");
        }catch(NoSuchElementException ex){
            System.out.println("没有正在执行的操作!");
        }catch(Exception exx){
            exx.printStackTrace();
        }finally{
            threadList.remove(thread);      //从List移除这条线程。
        }
    }

为了防止stop()方法调用时报错,我们需要写一个扫描器来扫描哪些线程run()方法是已经执行完毕而不能调用stop()方法,run()方法执行完毕的线程就把它从List移除

import java.lang.Thread.State;
import java.util.LinkedList;

import com.alee.utils.ThreadUtils;

/**
 * 保存每个执行操作的线程,并且定期清理已经结束的线程。
 * 主要用于“取消上次操作”功能。
 * @author g
 *
 */
public class ThreadListScaner implements Runnable{

    private LinkedList<Thread> threadList;
    public ThreadListScaner(){
        this.threadList = UIContext.getThreadList();
    }
    
    @Override
    public void run() {
        //2秒扫描一次
        while(true){
            ThreadUtils.sleepSafely(2000);
            LinkedList<Thread> tempThreadList = new LinkedList<Thread>(threadList);
            for(Thread thread : tempThreadList){
                State state = thread.getState();
                if(state.equals(State.TERMINATED)){        //如果是TERMINATED状态,则移除这条线程
                    threadList.remove(thread);
                }
            }
        }
    }
}

这里我把装线程的List缓存到一个叫UIContext的类里,其实就是一个装在各种全局可能需要用到的东西的类。

这个代码实现了一个功能:停止上一操作,每按一次停止按钮,就停止一条线程。

.