• Eclipse Job


    Job可以我们基于Eclipse的Java程序中,我们有很多种方式提供多任务的实现。熟悉Java的朋友立即会想到Java的Thread类,这是Java中使 用最多的一个实现多任务的类。Eclipse平台为多任务处理提供了自己的API,那就是Job以及UIJob。Eclipse中的Job是对Java Thread的一个封装,为我们实现多任务提供了更方便的接口。以下是Job的基本用法:

    清单 1. Job用法示例

                Job job = new Job(“Job Name”){
                     protected IStatus run(IProgressMonitor monitor) {
                        // 在这里添加你的任务代码
                        return Status.OK_STATUS;
                    }
                };
    job.schedule(1133);//delaytime
    job.setUser(true);//if true show UI
    job.setPriority(priority)

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

    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,将上面的顺序倒过来不就得了

    在Eclipse 中我们经常用到Display.asynchExec() 和Display.synchExec()来启动任务的执行。这两个方法主要为了方便我们完成界面操作的任务。以下是 Display.asynchExec()的用法,Display.synchExec()和它类似。

    在RCP中要在非UI线程中执行UI线程的操作,最简单的方式就是 display.syncExec或者display.asyncExec,一个是同步处理一个是异步处理,如果UI线程所需的时间较长的话,则应该使用 display.asyncExec,可以让程序并发允许。


    清单 2. Display.synchExec()用法示例

           Display.getDefault().asyncExec(new Runnable() {
    public void run() {
    // 在这里添加你的任务代码
    }
    });

    Eclipse中Job的实现

    Eclipse 的核心包中提供了一个JobManager类,它实现了IJobManager接口,Eclipse中Job的管理和调度都是由JobManager来实 现的。 JobManager维护有一个线程池,用来运行Job。当我们调用Job的schedule方法后,这个Job会被JobManager首先放到一个 Job运行的等待队列中去。之后,JobManager会通知线程池有新的Job加入了运行等待队列。线程池会找出一个空闲的线程来运行Job,如果没有 空闲线程,线程池会创建一个新的线程来运行Job。一旦Job运行完毕,运行Job的线程会返回到线程池中以备下次使用。 从上面Job运行的过程我们可以看到,JobManager介入了一个Job运行的全过程,它了解Job什么时候开始,什么时候结束,每一时候Job的运 行状态。JobManager将这些Job运行的信息以接口的方式提供给用户,同时它也提供了接口让我们可以介入Job的调度等,从而我们拥有了更加强大 的控制Job的能力。

    为了我们更方便的了解Job所处的状态,JobManager设置Job的一个状态标志位,我们可以通过Job的getState方法获得Job当前的状态值以了解其状态:

    • NONE:当一个Job刚构造的时候,Job就会处于这种状态。当一个Job执行完毕(包括被取消)后,Job的状态也会变回这种状态。
    • WAITING:当我们调用了Job的shedule方法,JobManager会将Job放入等待运行的Job队列,这时Job的状态为WAITING.
    • RUNNING:当一个Job开始执行,Job的状态会变为RUNNING。
    • SLEEPING: 当我们调用Job的sleep方法后,Job会变成这一状态。当我们调用schudule方法的时候带上延时的参数,Job的状态也会转入这一状态,在这 一段延时等待的时间中,Job都处于这一状态。这是一种睡眠状态,Job在这种状态中时不能马上转入运行。我们可以调用Job的wakeup方法来将 Job唤醒。这样,Job又会转入WAITING状态等待运行。

    Eclipse中的UI线程

    在Eclipse的线程处理中,有一个UI线程的概念。Eclipse程序中的主线程是一个特殊的线程,程序启动后会先执行这个线程,也就是我们的 main()函数所在的线程。作为桌面应用程序,我们的主线程主要负责界面的响应以及绘制界面元素,所以通常我们也叫它UI线程。

    以下代码,编过SWT应用程序的读者会非常熟悉。它一般出现在main函数的结尾。下面来仔细分析一下它的详细情况。

    while (!shell.isDisposed()) {          //当窗口未释放时

        if (!display.readAndDispatch()) //如果display对象事件队列中没有了等待的事件,就让该线程进入等待状态

            display.sleep();   //可以将display 理解为UI线程,即主线程。

    }

    上面的程序实际上就是我们UI线程的处理 逻辑:当程序启动后,UI线程会读取事件等待队列,看有没有事件等待处理。如果有,它会进行相应处理,如果没有它会进入睡眠状态。如果有新的事件到来,它 又会被唤醒,进行处理。UI线程所需要处理的事件包括用户的鼠标和键盘操作事件,操作系统或程序中发出的绘制事件。一般来说,处理事件的过程也就是响应用户操作的过程。

    一个好的桌面应用程序需要对用户的操作作出最快的响应,也就是说我们的UI线程必须尽快的处理 各种事件。从我们程序的角度来说,在UI线程中我们不能进行大量的计算或者等待,否则用户操作事件得不到及时的处理。通常,如果有大量的计算或者需要长时 间等待(例如进行网络操作或者数据库操作)时,我们必须将这些长时间处理的程序单独开辟出一个线程来执行。这样虽然后台运行着程序,但也不会影响界面上的 操作。

    除主线程之外的所有线程都是非UI线程。 在Eclipse程序中,我们所有对界面元素的操作都必须放到UI线程中来执行,否则会抛出Exception,所以我们要区分出UI线程和非UI线程,保证我们对UI的操作都在UI线程中执行。

    如何判断当前线程是否UI线程: 你可以通过调用Display.getCurrent()来知道当前线程是否是UI线程。如果Display.getCurrent()返回为空,表示当前不是UI线程。

    Eclipse中使用线程的几种典型情况

    Eclipse为Job提供了3个扩展:WorkspaceJob,UIJob,WorkbenchJob.算上Job本身构成了eclipse对多线程的支持。

    WorkspaceJob是为修改资源文件增加的扩展,常见的对文件的打开,保存,等等操作一般需要在这个类中执行。与WorkspaceJob对应的是IWorkspaceRunnable。

    UIJob是在 UI线程上干活,所以大家使用时就要注意效率了。因为这个UIJob运行时UI是不刷新的看上去可能像死掉一样。所以数据的处理(长时间运行的程序)需要使用Job基类在UI线程外部运行,SWT界面的刷新,需要在UIJob中.

  • 相关阅读:
    【工具篇】抓包中的王牌工具—Fiddler (2-工具介绍)
    SQL注入攻击的常见方式及测试方法
    Xshell访问和连接Linux
    【户口篇】换房过程中,户口怎么迁移?
    【计算机篇】二维码解析、短地址生成器
    【工具篇】Sublime Text 2/3 安装汉化破解、插件包安装教程详解
    【通用】登录功能测试用例
    【工具篇】接口测试神器 -- Postman 入门教程
    【生活篇】微信运动刷步,高达98000!微信运动计步作弊教程!
    关于The C compiler "arm-none-eabi-gcc" is not able to compile a simple test program. 的错误自省...
  • 原文地址:https://www.cnblogs.com/muyuhu/p/3910341.html
Copyright © 2020-2023  润新知