Eclipse Job

Job能夠咱們基於Eclipse的Java程序中,咱們有不少種方式提供多任務的實現。熟悉Java的朋友當即會想到Java的Thread類,這是Java中使 用最多的一個實現多任務的類。Eclipse平臺爲多任務處理提供了本身的API,那就是Job以及UIJob。Eclipse中的Job是對Java Thread的一個封裝,爲咱們實現多任務提供了更方便的接口。如下是Job的基本用法:shell

清單 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;
      }
    };
eclipse

和Job用起來沒有什麼區別的,經過schedule()方法啓動Job,若是我 們想讓這個Job在後臺悄悄的執行的話能夠設置job.setUser(false); 這樣就好了,想顯示對話框設置setUser(true)就好了,若是咱們想讓Job進度對話框顯示進度條的話能夠 monitor.beginTask("正在查詢數據......", IProgressMonitor.UNKNOWN);這樣對話框是的進度就會不停的跑來跑去的了異步

剛纔提到的,咱們但願用Job查詢數據,用UIJob顯示數據,這是涉及到Job執行的前後順序,咱們想讓Job執行後在執行UIJob,這是能夠給Job設置調度規則,這樣就會排隊執行async

//調度規則,設置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);
this

 

這樣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中.

相關文章
相關標籤/搜索