使用Eclipse Job执行异步线程的处理

来源:互联网 发布:线性代数a 算法 编辑:程序博客网 时间:2024/06/05 19:43

   最近在项目开发过程中,需要通过后台处理大量的业务数据,而在UI界面发出查询命令到后台返回查询结果需要时间,特别是这些数据又需要从数据库或者远程网络获取,通常情况下UI界面会一直等待查询方法执行完了才会进行响应,在这个过程中看起来界面好像死了一样,给用户的体验是非常的差,如果我们能通过一个进度条显示当前的进度,就算做一个假的进度显示也好,可以打发用户无聊的时间嘛,这时候我们就要考虑使用多线程了。

  值得高兴的是我们使用Eclipse开发项目的话,可以使用Eclipse提供的多线程支持,在RCP中要在非UI线程中执行UI线程的操作,最简单的方式就是display.syncExec或者display.asyncExec,一个是同步处理一个是异步处理,如果UI线程所需的时间较长的话,则应该使用display.asyncExec,可以让程序并发允许。

 在这里推荐使用Job这个类,而不是Java中的Thread,为什么?先列出它的好处来:

  我们可以在它的run方法中执行比较消耗时间的方法,而且可以将它转入到后台允许,可以不打扰现在的操作,不过这个方法唯一的缺点是不能访问UI线程,可惜,如果我们要访问UI线程的话就要使用UIJob这个类了,其实UIJob是Job的一个子类,这个方法就可以访问UI线程了,不过这个方法在执行的时候意味着我们的程序不会再响应界面操作,也不会刷新,这样,用户会觉得我们的程序象死了一样没有反应。

  • Job是可重用的工作单元,一个Job我们可以很方便的让它多次执行。
  • Job提供了方便的接口,使得我们在处理中能够很方便的与外界交流,报告当前的执行进度
  • Eclipse提供了相应的机制使得程序员可以方便的介入Job的调度,例如我们可以方便的实现每次只有一个同一类型的Job在运行
  • Eclipse缺省提供了Job管理的程序,可以查看当前所有的Job和它们的进度,也提供UI终止、暂停、继续指定的Job
  • 使用Job可以提高程序的性能,节省线程创建和销毁的开销。Eclipse中的Job封装了线程池的实现。当我们启动一个Job时,Eclipse不会马上新建一个Thread,它会在它的线程池中寻找是否有空闲的线程,如果有空闲线程,就会直接用空闲线程运行你的Job。一个Job终止时,它所对应的线程也不会立即终止,它会被返回到线程池中以备重复利用。这样,我们可以节省创建和销毁线程的开销

有了这些优点应该能够吸引你了吧,使用起来也非常的简单

 job1 = new Job("正在查询数据......") {
      
protected
 IStatus run(IProgressMonitor monitor) {
        monitor.beginTask(
"正在查询数据......"
, IProgressMonitor.UNKNOWN);
            
//处理业务逻辑


           
return Status.CANCEL_STATUS;
        }
        
return
 Status.OK_STATUS;
      }
    };

我们可以在Run方法中处理我们的业务逻辑,不过这里只能执行非UI线程,如果访问UI线程会抛出个非法的线程访问异常,我们可以通过另外一个方式来处理UI线程那就是UIJob,其实UIJob是Job的子类,这两个东西的区别是Job执行的时候可以响应界面的操作,而UIJob的话会阻塞其他线程的执行,如果在UIJob中执行耗时的任务的话会让人产生程序死机的错觉,最好的方法是结合两个一起使用,比如Job负责从后台提取数据,而UIJob将数据展示到前台界面中,下面是UIJob是使用方法

job2 = new UIJob("正在更新界面......") {
      
public
 IStatus runInUIThread(IProgressMonitor monitor) {
        //处理业务逻辑


        return Status.CANCEL_STATUS;
      }
    };

和Job用起来没有什么区别的,通过schedule()方法启动Job,如果我们想让这个Job在后台悄悄的执行的话可以设置job.setUser(false); 这样就行了,想显示对话框设置setUser(true)就行了,如果我们想让Job进度对话框显示进度条的话可以monitor.beginTask("正在查询数据......", IProgressMonitor.UNKNOWN);这样对话框是的进度就会不停的跑来跑去的了

  刚才提到的,我们希望用Job查询数据,用UIJob显示数据,这是涉及到Job执行的先后顺序,我们想让Job执行后在执行UIJob,这是可以给Job设置调度规则,这样就会排队执行

//调度规则,设置Job先后调用的顺序
    ISchedulingRule Schedule_RULE = new ISchedulingRule() {
      
public boolean
 contains(ISchedulingRule rule) {
        
return this
.equals(rule);
      }

      
public boolean
 isConflicting(ISchedulingRule rule) {
        
return this
.equals(rule);
      }
    };

使用如下:

   job1.setRule(Schedule_RULE);
    job2.setRule(Schedule_RULE);

这样job1执行完成后Job2才会执行,如果想job2执行后在执行Job1,将上面的顺序倒过来不就得了

原创粉丝点击