<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    gembin

    OSGi, Eclipse Equinox, ECF, Virgo, Gemini, Apache Felix, Karaf, Aires, Camel, Eclipse RCP

    HBase, Hadoop, ZooKeeper, Cassandra

    Flex4, AS3, Swiz framework, GraniteDS, BlazeDS etc.

    There is nothing that software can't fix. Unfortunately, there is also nothing that software can't completely fuck up. That gap is called talent.

    About Me

     

    Eclipse RCP中多線程Job使用

    本文分析了Eclipse中多線程程序的實現(xiàn),討論了在Eclipse客戶端程序開發(fā)中應(yīng)用多線程的方法和要注意的問題,同時也討論了多線程程序的一些調(diào)試和問題解決的方法。

    Eclipse 作為一個開發(fā)平臺,使用越來越廣泛,基于Eclipse Rich Client Platform開發(fā)的客戶端程序也越來越多。在當(dāng)今越來越復(fù)雜的應(yīng)用環(huán)境中,我們的客戶端程序不可避免的要同時進行多任務(wù)的處理。一個優(yōu)異的客戶端程序 都會允許用戶同時啟動多個任務(wù),從而大大提高用戶的工作效率以及用戶體驗。本文中我們來談?wù)凟clipse中實現(xiàn)多任務(wù)的方式。

    在 我們基于Eclipse的Java程序中,我們有很多種方式提供多任務(wù)的實現(xiàn)。熟悉Java的朋友立即會想到Java的Thread類,這是Java中使 用最多的一個實現(xiàn)多任務(wù)的類。Eclipse平臺為多任務(wù)處理提供了自己的API,那就是Job以及UIJob。Eclipse中的Job是對Java Thread的一個封裝,為我們實現(xiàn)多任務(wù)提供了更方便的接口。以下是Job的基本用法:

    清單 1. Job用法示例

                    Job job = new Job(“Job Name”){
    protected IStatus run(IProgressMonitor monitor) {

    // 在這里添加你的任務(wù)代碼
    return Status.OK_STATUS;
    }
    };
    job.schedule(1133);//delaytime
    job.setUser(true);//if true show UI
    job.setPriority(priority)

    在Eclipse 中我們也會經(jīng)常用到Display.asynchExec() 和Display.synchExec()來啟動任務(wù)的執(zhí)行。這兩個方法主要為了方便我們完成界面操作的任務(wù)。以下是 Display.asynchExec()的用法,Display.synchExec()和它類似。


    清單 2. Display.synchExec()用法示例
           Display.getDefault().asyncExec(new Runnable() {
    public void run() {
    // 在這里添加你的任務(wù)代碼
    }
    });

    通常,在Eclipse中我們最好使用Eclipse提供的Job接口來實現(xiàn)多任務(wù),而不是使用Java的thread。為什么呢?主要有以下幾個原因:

    • Job是可重用的工作單元,一個Job我們可以很方便的讓它多次執(zhí)行。
    • Job提供了方便的接口,使得我們在處理中能夠很方便的與外界交流,報告當(dāng)前的執(zhí)行進度
    • Eclipse提供了相應(yīng)的機制使得程序員可以方便的介入Job的調(diào)度,例如我們可以方便的實現(xiàn)每次只有一個同一類型的Job在運行
    • Eclipse缺省提供了Job管理的程序,可以查看當(dāng)前所有的Job和它們的進度,也提供UI終止、暫停、繼續(xù)指定的Job
    • 使 用Job可以提高程序的性能,節(jié)省線程創(chuàng)建和銷毀的開銷。Eclipse中的Job封裝了線程池的實現(xiàn)。當(dāng)我們啟動一個Job時,Eclipse不會馬上 新建一個Thread,它會在它的線程池中尋找是否有空閑的線程,如果有空閑線程,就會直接用空閑線程運行你的Job。一個Job終止時,它所對應(yīng)的線程 也不會立即終止,它會被返回到線程池中以備重復(fù)利用。這樣,我們可以節(jié)省創(chuàng)建和銷毀線程的開銷

    下面我們從幾個方面來討論Eclipse中Job的實現(xiàn)和使用方面的問題。

    Eclipse中Job的實現(xiàn)

    Eclipse 的核心包中提供了一個JobManager類,它實現(xiàn)了IJobManager接口,Eclipse中Job的管理和調(diào)度都是由JobManager來實 現(xiàn)的。 JobManager維護有一個線程池,用來運行Job。當(dāng)我們調(diào)用Job的schedule方法后,這個Job會被JobManager首先放到一個 Job運行的等待隊列中去。之后,JobManager會通知線程池有新的Job加入了運行等待隊列。線程池會找出一個空閑的線程來運行Job,如果沒有 空閑線程,線程池會創(chuàng)建一個新的線程來運行Job。一旦Job運行完畢,運行Job的線程會返回到線程池中以備下次使用。 從上面Job運行的過程我們可以看到,JobManager介入了一個Job運行的全過程,它了解Job什么時候開始,什么時候結(jié)束,每一時候Job的運 行狀態(tài)。JobManager將這些Job運行的信息以接口的方式提供給用戶,同時它也提供了接口讓我們可以介入Job的調(diào)度等,從而我們擁有了更加強大 的控制Job的能力。

    為了我們更方便的了解Job所處的狀態(tài),JobManager設(shè)置Job的一個狀態(tài)標志位,我們可以通過Job的getState方法獲得Job當(dāng)前的狀態(tài)值以了解其狀態(tài):

    • NONE:當(dāng)一個Job剛構(gòu)造的時候,Job就會處于這種狀態(tài)。當(dāng)一個Job執(zhí)行完畢(包括被取消)后,Job的狀態(tài)也會變回這種狀態(tài)。
    • WAITING:當(dāng)我們調(diào)用了Job的shedule方法,JobManager會將Job放入等待運行的Job隊列,這時Job的狀態(tài)為WAITING.
    • RUNNING:當(dāng)一個Job開始執(zhí)行,Job的狀態(tài)會變?yōu)镽UNNING。
    • SLEEPING: 當(dāng)我們調(diào)用Job的sleep方法后,Job會變成這一狀態(tài)。當(dāng)我們調(diào)用schudule方法的時候帶上延時的參數(shù),Job的狀態(tài)也會轉(zhuǎn)入這一狀態(tài),在這 一段延時等待的時間中,Job都處于這一狀態(tài)。這是一種睡眠狀態(tài),Job在這種狀態(tài)中時不能馬上轉(zhuǎn)入運行。我們可以調(diào)用Job的wakeup方法來將 Job喚醒。這樣,Job又會轉(zhuǎn)入WAITING狀態(tài)等待運行。

    Eclipse中的UI線程

    另 外,在Eclipse的線程處理中,有一個UI線程的概念。Eclipse程序中的主線程是一個特殊的線程,程序啟動后會先執(zhí)行這個線程,也就是我們的 main()函數(shù)所在的線程。作為桌面應(yīng)用程序,我們的主線程主要負責(zé)界面的響應(yīng)以及繪制界面元素,所以通常我們也叫它UI線程。

    以下代碼,編過SWT應(yīng)用程序的讀者會非常熟悉。它一般出現(xiàn)在main函數(shù)的結(jié)尾。下面來仔細分析一下它的詳細情況。

    //當(dāng)窗口未釋放時
    while (!shell.isDisposed()) {

    //如果display對象事件隊列中沒有了等待的事件,就讓該線程進入等待狀態(tài)
    if (!display.readAndDispatch())
    display.sleep();

    }

    上面的程序?qū)嶋H上就是我們UI線程的處理 邏輯:當(dāng)程序啟動后,UI線程會讀取事件等待隊列,看有沒有事件等待處理。如果有,它會進行相應(yīng)處理,如果沒有它會進入睡眠狀態(tài)。如果有新的事件到來,它 又會被喚醒,進行處理。UI線程所需要處理的事件包括用戶的鼠標和鍵盤操作事件,操作系統(tǒng)或程序中發(fā)出的繪制事件。一般來說,處理事件的過程也就是響應(yīng)用 戶操作的過程。

    一個好的桌面應(yīng)用程序需要對用戶的操作作出最快的響應(yīng),也就是說我們的UI線程必須盡快的處理 各種事件。從我們程序的角度來說,在UI線程中我們不能進行大量的計算或者等待,否則用戶操作事件得不到及時的處理。通常,如果有大量的計算或者需要長時 間等待(例如進行網(wǎng)絡(luò)操作或者數(shù)據(jù)庫操作)時,我們必須將這些長時間處理的程序單獨開辟出一個線程來執(zhí)行。這樣雖然后臺運行著程序,但也不會影響界面上的 操作。

    除主線程之外的所有線程都是非UI線程。 在Eclipse程序中,我們所有對界面元素的操作都必須放到UI線程中來執(zhí)行,否則會拋出Exception,所以我們要區(qū)分出UI線程和非UI線程,保證我們對UI的操作都在UI線程中執(zhí)行。

    如何判斷當(dāng)前線程是否UI線程: 你可以通過調(diào)用Display.getCurrent()來知道當(dāng)前線程是否是UI線程。如果Display.getCurrent()返回為空,表示當(dāng)前不是UI線程。

    Eclipse中使用線程的幾種典型情況

    • 控制Job的并發(fā)運行

    對 于某些Job,為了避免并發(fā)性問題,我們希望同時只有一個這樣的Job在運行,這時我們需要控制Job的并發(fā)運行。在另一種情況下,我們也需要控制Job 的并發(fā)運行:我們在程序中對于一個任務(wù),我們有可能會啟動一個Job來執(zhí)行,對于少量的任務(wù)來說,這是可行的,但是如果我們預(yù)測可能會同時有大量的任務(wù), 如果每一個任務(wù)啟動一個Job,我們同時啟動的Job就會非常多。這些Job會侵占大量的資源,影響其他任務(wù)的執(zhí)行。 我們可以使用Job的rule來實現(xiàn)控制Job的并發(fā)執(zhí)行。簡單的我們可以通過下面的代碼實現(xiàn)。我們先定義一個如下rule:

    	private ISchedulingRule Schedule_RULE = new ISchedulingRule() {
    public boolean contains(ISchedulingRule rule) {
    return this.equals(rule);
    }
    public boolean isConflicting(ISchedulingRule rule) {
    return this.equals(rule);
    }
    };

    對于需要避免同時運行的Job,我們可以將它們的rule設(shè)成上面定義的rule。如:

    	myjob1.setRule(Schedule_RULE);
    myjob2.setRule(Schedule_RULE);

    這樣對于myjob1和myjob2這兩個Job,它們不會再同時執(zhí)行。Myjob2會等待myjob1執(zhí)行完再執(zhí)行。這是由Eclipse的JobManager來提供實現(xiàn)的。JobManager可以保證所有啟動的Job中,任意兩個Job的rule是沒有沖突的。 我們在上面定義的rule是最簡單的。我們可以重寫isConflicting函數(shù)來實現(xiàn)一些更加復(fù)雜的控制,比如控制同時同類型的Job最多只有指定的個數(shù)在運行。 但是我們要注意,isConflicting方法不能過于復(fù)雜。一旦一個Job的rule與其他Job的rule有沖突,isConflicting方法會調(diào)用很多次。如果其中的計算過于復(fù)雜,會影響整體的性能。

    • 根據(jù)需要執(zhí)行Job

    由 于我們有的Job有可能不是立即執(zhí)行的,在有些情況下,等到該Job準備執(zhí)行的時候,該Job所要執(zhí)行的任務(wù)已經(jīng)沒有意義了。這時,我們可以使用Job的 shouldSchedule()和shouldRun()來避免Job的運行。在我們定義一個Job時,我們可以重載shouldSchedule和 shouldRun方法。在這些方法中,我們可以檢查Job運行的一些先決條件,如果這些條件不滿足,我們就可以返回false。JobManager在 安排Job運行時,它會先調(diào)用該Job的shouldSchedule方法,如果返回為false,JobManager就不會再安排這個Job運行了。 同樣,JobManager在真正啟動一個線程運行一個Job前,它會調(diào)用該Job的shouldRun方法,如果返回false,它不再運行這個 Job。在下面的例子中,我們希望啟動一個Job在十秒鐘之后更新文本框中的內(nèi)容。為了保證我們的Job運行時是有意義的,我們需要確保我們要更新的文本 框沒有被銷毀,我們重載了shouldSchedule和shouldRun方法。

    Text text = new Text(parent,SWT.NONE);
    UIJob refreshJob = new UIJob(“更新界面”){
    public IStatus runInUIThread(IProgressMonitor monitor) {

    text.setText(“新文本”);
    return Status.OK_STATUS;
    }
    public boolean shouldSchedule(){
    return !text.isDisposed();
    }
    public boolean shouldRun(){
    return !text.isDisposed();
    }
    };
    refreshJob.schedule(10000);

    • 在UI線程中涉及長時間處理的任務(wù)

    我 們經(jīng)常碰到這樣一種情況:用戶操作菜單或者按鈕會觸發(fā)查詢大量數(shù)據(jù),數(shù)據(jù)查詢完后更新表格等界面元素。用戶點擊菜單或者按鈕所觸發(fā)的處理程序一般處于UI 線程,為了避免阻塞UI,我們必須把數(shù)據(jù)查詢等費時的工作放到單獨的Job中執(zhí)行,一旦數(shù)據(jù)查詢完畢,我們又必須更新界面,這時我們又需要使用UI線程進 行處理。下面是處理這種情況的示例代碼:

    	button.addSelectionListener(new SelectionListener(){
    public void widgetSelected(SelectionEvent e){
    perform();
    }

    public void widgetDefaultSelected(SelectionEvent e){
    perform();
    }

    private void perform(){
    Job job = new Job(“獲取數(shù)據(jù)”){
    protected IStatus run(IProgressMonitor monitor){
    // 在此添加獲取數(shù)據(jù)的代碼
    Display.getDefault().asyncExec(new Runnable(){
    public void run(){
    // 在此添加更新界面的代碼
    }
    });
    }
    };
    job.schedule();
    }

    });

    • 延時執(zhí)行Job,避免無用的Job運行

    我們經(jīng)常需要根據(jù)選中的對象刷新我們部分的界面元素。如果我們連續(xù)很快的改變選擇,而每次刷新界面涉及到的區(qū)域比較大時,界面會出現(xiàn)閃爍。從用戶的角度來說,我們很快的改變選擇,希望看到的只是最后選中的結(jié)果,中間的界面刷新都是不必要的。

    在Jface 中,StructuredViewer提供了addPostSelectionChangedListener方法。如果我們使用這個方法監(jiān)聽 selectionChanged事件,當(dāng)用戶一直按著方向鍵改變選中時,我們只會收到一個selectionChanged事件。這樣我們可以避免過度 的刷新界面。

    實際上,Jface中就是通過延時執(zhí)行Job來實現(xiàn)這一功能的。我們也可以自己實現(xiàn)類似功能:

    	private final static Object UPDATE_UI_JOBFAMILY = new Object();
    tableviewer. addSelectionChangedListener (new ISelectionChangedListener (){

    public void selectionChanged(SelectionChangedEvent event){
    Job.getJobManager().cancel(UPDATE_UI_JOBFAMILY);
    new UIJob("更新界面") {
    protected IStatus runInUIThread (IProgressMonitor monitor) {
    //更新界面
    return Status.OK_STATUS;
    }

    public boolean belongsTo(Object family){
    return family== UPDATE_UI_JOBFAMILY;
    }

    }.schedule(500);
    }
    });

    首 先,我們需要將界面更新的代碼放到一個UIJob中,同時我們將Job延時500毫秒執(zhí)行(我們可以根據(jù)需要改變延時的時間)。如果下一個 selectionChanged事件很快到來,我們的調(diào)用Job.getJobManager().cancel (UPDATE_UI_JOBFAMILY)將以前未運行的Job取消,這樣只有最后一個Job會真正運行。

    • 在UI線程中等待非UI線程的結(jié)束

    有 時,我們在UI線程中需要等待一個非UI線程執(zhí)行完,我們才能繼續(xù)執(zhí)行。例如,我們在UI線程中要顯示某些數(shù)據(jù),但是這些數(shù)據(jù)又需要從數(shù)據(jù)庫或者遠程網(wǎng)絡(luò) 獲取。于是,我們會啟動一個非UI的線程去獲取數(shù)據(jù)。而我們的UI線程必須要等待這個非UI線程執(zhí)行完成,我們才能繼續(xù)執(zhí)行。當(dāng)然,一種簡單的實現(xiàn)方法是 使用join。我們可以在UI線程中調(diào)用非UI線程的join方法,這樣我們就可以等待它執(zhí)行完了,我們再繼續(xù)。但是,這會有一個問題。當(dāng)我們的UI線程 等待時,意味著我們的程序不會再響應(yīng)界面操作,也不會刷新。這樣,用戶會覺得我們的程序象死了一樣沒有反應(yīng)。這時,我們可以使用ModalContext 類。你可以將你要執(zhí)行的獲取數(shù)據(jù)的任務(wù)用ModalContext的run方法來運行(如下)。ModalContext會將你的任務(wù)放到一個獨立的非 UI線程中執(zhí)行,并且等待它執(zhí)行完再繼續(xù)執(zhí)行。與join方法不同的是,ModalContext在等待時不會停止UI事件的處理。這樣我們的程序就不會 沒有響應(yīng)了。

    try {
    ModalContext.run(new IRunnableWithProgress(){
    public void run(IProgressMonitor monitor)
    throws InvocationTargetException, InterruptedException {
    /*需要在非UI線程中執(zhí)行的代碼*/
    ModalContext.checkCanceled(monitor);
    }
    }, true, new NullProgressMonitor(), Display.getCurrent());
    } catch (InvocationTargetException e) {

    } catch (InterruptedException e) {
    }

    • 針對相關(guān)聯(lián)的Job統(tǒng)一進行處理

    有 時,我們需要對相關(guān)聯(lián)的Job一起處理。例如需要同時取消這些Job,或者等待所有這些Job結(jié)束。這時我們可以使用Job Family。對于相關(guān)聯(lián)的Job,我們可以將它們設(shè)置成同一個Job Family。我們需要重載Job的belongsTo方法以設(shè)置一個Job的Job Family。

    Private Object MY_JOB_FAMILY = new Object();
    Job job = new Job(“Job Name”){
    protected IStatus run(IProgressMonitor monitor) {
    // 在這里添加你的任務(wù)代碼
    return Status.OK_STATUS;
    }

    public boolean belongsTo(Object family){
    return MY_JOB_FAMILY.equals(family);
    }
    };

    我們可以使用JobManager的一系列方法針對Job Family進行操作:

    Job.getJobManager().cancel(MY_JOB_FAMILY); //取消所有屬于MY_JOB_FAMILY的所有Job
    Job.getJobManager().join(MY_JOB_FAMILY); //等待屬于MY_JOB_FAMILY的所有Job結(jié)束
    Job.getJobManager().sleep(MY_JOB_FAMILY); //將所有屬于MY_JOB_FAMILY的Job轉(zhuǎn)入睡眠狀態(tài)
    Job.getJobManager().wakeup(MY_JOB_FAMILY); //將所有屬于MY_JOB_FAMILY的Job喚醒

    線程死鎖的調(diào)試和解決技巧

    一 旦我們使用了線程,我們的程序中就有可能有死鎖的發(fā)生。一旦發(fā)生死鎖,我們發(fā)生死鎖的線程會沒有響應(yīng),導(dǎo)致我們程序性能下降。如果我們的UI線程發(fā)生了死 鎖,我們的程序會沒有響應(yīng),必須要重啟程序。所以在我們多線程程序開發(fā)中,發(fā)現(xiàn)死鎖的情況,解決死鎖問題對提高我們程序的穩(wěn)定性和性能極為重要。

    如果我們發(fā)現(xiàn)程序運行異常(例如程序沒有響應(yīng)),我們首先要確定是否發(fā)生了死鎖。通過下面這些步驟,我們可以確定是否死鎖以及死鎖的線程:

    • 在Eclipse中以Debug模式運行程序
    • 執(zhí)行響應(yīng)的測試用例重現(xiàn)問題
    • 在Eclipse的Debug View中選中主線程(Thread[main]),選擇菜單Run->Suspend。這時Eclipse會展開主線程的函數(shù)調(diào)用棧,我們就可以看到當(dāng)前主線程正在執(zhí)行的操作。
    • 通常,Eclipse在等待用戶的操作,它的函數(shù)調(diào)用棧會和以下類似:


      圖片示例
      圖片示例

    • 如果主線程發(fā)生死鎖,函數(shù)調(diào)用棧的最上層一般會是你自己的函數(shù)調(diào)用,你可以查看一下你當(dāng)前的函數(shù)調(diào)用以確定主線程在等待什么
    • 使用同樣的方法查看其他線程,特別是那些等待UI線程的線程

    我們需要找出當(dāng)前線程相互的等待關(guān)系,以便找出死鎖的原因。我們找出死鎖的線程后就可以針對不同情況進行處理:

    • 減小鎖的粒度,增加并發(fā)性
    • 調(diào)整資源請求的次序
    • 將需要等待資源的任務(wù)放到獨立的線程中執(zhí)行

    Job使用中要注意的問題

    • 不 要在Job中使用Thread.sleep方法。如果你想要讓Job進入睡眠狀態(tài),最好用Job的sleep方法。雖然,使用Thread.sleep和 Job的sleep方法達到的效果差不多,但是它們實現(xiàn)的方式完全不同,對系統(tǒng)的影響也不一樣。我們知道Eclipse中Job是由Eclipse的 JobManager來管理的。如果我們調(diào)用Job的sleep方法,JobManager會將Job轉(zhuǎn)入睡眠狀態(tài),與其對應(yīng)的線程也會重新放入線程池等 待運行其他Job。而如果我們在Job中直接調(diào)用Thread.sleep方法,它會直接使運行Job的線程進入睡眠狀態(tài),其他Job就不可能重用這個線 程了。同時,雖然運行該Job的線程進入了睡眠狀態(tài),Job的狀態(tài)還是Running(運行狀態(tài)),我們也不能用Job的wakeup方法喚醒該Job了
    • Job 的取消。一般我們會直觀的認為,一旦調(diào)用Job的cancel方法,Job就會停止運行。實際上,這并不一定正確,當(dāng)Job處于不同的狀態(tài)時,我們調(diào)用 Job的cancel方法所起的效果是不同的。當(dāng)Job在WAITING狀態(tài)和SLEEPING狀態(tài)時,一旦我們調(diào)用cancel方法, JobManager會將Job直接從等待運行的隊列中刪除,Job不會再運行了,這時cancel方法會返回true。但是如果Job正在運行, cancel方法調(diào)用并不會立即終止Job的運行,它只會設(shè)定一個標志,指明這個Job已經(jīng)被取消了。我們可以使用Job的run方法傳入的參數(shù) IProgressMonitor monitor,這個參數(shù)的isCanceled方法會返回Job是否被取消的狀態(tài)。如果需要,我們必須在我們的代碼的適當(dāng)位置檢查Job是否被取消的標 志,作出適當(dāng)?shù)捻憫?yīng)。另外,由于調(diào)用Job的cancel方法不一定立即終止Job,如果我們需要等待被取消的Job運行完再執(zhí)行,我們可以用如下代碼:
       if (!job.cancel())
      job.join();

    • Join方法的使用。由于join方法會導(dǎo)致一個線程等待另一個線程,一旦等待線程中擁有一個被等待線程所需要的鎖,就會產(chǎn)生死鎖。當(dāng)我們的線程中需要用到同步時,這種死鎖的情況非常容易出現(xiàn),所以我們使用join時必須非常小心,盡量以其他方法替代。
    • 避 免過時的Job造成的錯誤。由于我們啟動的線程并不一定是馬上執(zhí)行的,當(dāng)我們的Job開始運行時,情況可能發(fā)生了變化。我們在Job的處理代碼中要考慮到 這些情況。一種典型的情況是,我們在啟動一個對話框或者初始化一個ViewPart時,我們會啟動一些 Job去完成一些數(shù)據(jù)讀取的工作,一旦數(shù)據(jù)讀取結(jié)束,我們會啟動新的UI Job更新相應(yīng)的UI。有時,用戶在打開對話框或者View后,馬上關(guān)閉了該對話框或者View。這時我們啟動的線程并沒有被中斷,一旦在Job中再去更 新UI,就會出錯。在我們的代碼中必須作相應(yīng)的處理。所以,我們在線程中更新界面元素之前,我們必須先檢查相應(yīng)的控件是否已經(jīng)被dispose了

    結(jié)束語

    在我們進行基于Eclipse的客戶端開發(fā)時,使用多線程可以大大的提供我們的程序并發(fā)處理能力,同時對于提高用戶體驗也有很好的幫助。但是,多線程程序也有其不利的一面,我們也不要濫用線程:

    • 首先,多線程程序會大大的提高我們程序的復(fù)雜度,使得我們的開發(fā)和調(diào)試更加困難
    • 其次,過多的線程容易引發(fā)死鎖、數(shù)據(jù)同步等并發(fā)問題的發(fā)生
    • 另外,由于線程創(chuàng)建和銷毀需要開銷,程序的整體性能可能因為過多線程的使用而下降

    所以,我們在使用線程時一定要謹慎。本文對Eclipse線程的討論,希望能對大家使用線程有所幫助。由于實際情況較為復(fù)雜,文中所提到的方法僅供參考,讀者對于不同的實際問題需要進行具體分析,從而找出最佳的解決方案。

    posted on 2008-03-21 17:40 gembin 閱讀(6595) 評論(0)  編輯  收藏 所屬分類: Eclipse RCP 、SWT

    導(dǎo)航

    統(tǒng)計

    常用鏈接

    留言簿(6)

    隨筆分類(440)

    隨筆檔案(378)

    文章檔案(6)

    新聞檔案(1)

    相冊

    收藏夾(9)

    Adobe

    Android

    AS3

    Blog-Links

    Build

    Design Pattern

    Eclipse

    Favorite Links

    Flickr

    Game Dev

    HBase

    Identity Management

    IT resources

    JEE

    Language

    OpenID

    OSGi

    SOA

    Version Control

    最新隨筆

    搜索

    積分與排名

    最新評論

    閱讀排行榜

    評論排行榜

    free counters
    主站蜘蛛池模板: 三年片在线观看免费大全电影 | 亚洲中文久久精品无码ww16| EEUSS影院WWW在线观看免费| 亚洲阿v天堂在线| 美女视频黄a视频全免费| 尤物视频在线免费观看| 亚洲最大福利视频网站| 免费a级毛片在线观看| 一区二区免费视频| 免费的黄网站男人的天堂 | 国产精品亚洲mnbav网站 | 精品亚洲视频在线观看| 国产v精品成人免费视频400条| 牛牛在线精品观看免费正 | 亚洲尹人香蕉网在线视颅| **一级一级毛片免费观看| 狠狠亚洲婷婷综合色香五月排名| 国产在线观看免费视频软件 | 一个人看的在线免费视频| 久久精品国产亚洲av麻豆图片| 国产亚洲欧洲Aⅴ综合一区| 在线免费视频一区| 亚洲免费观看网站| 久久国产免费观看精品| 一边摸一边爽一边叫床免费视频| 亚洲欧洲无码AV不卡在线| 久久亚洲国产成人精品性色| 国产av无码专区亚洲av果冻传媒| 日本不卡视频免费| 精品国产一区二区三区免费看| 67pao强力打造国产免费| 99久久免费观看| 久久一区二区三区免费播放| 99久久精品毛片免费播放| 亚洲五月午夜免费在线视频| 羞羞视频免费网站日本| 曰批免费视频播放在线看片二| 一级黄色片免费观看| 鲁啊鲁在线视频免费播放| xxxx日本在线播放免费不卡| 毛片基地看看成人免费|