天天看點

Eclipse中的Job

最近在項目開發過程中,需要通過背景處理大量的業務資料,而在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,将上面的順序倒過來不就得了

本文來自CSDN部落格,轉載請标明出處:http://blog.csdn.net/vwpolo/archive/2008/03/31/2234201.aspx