久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Eclipse客戶端程序中多線程的使用

 LibraryPKU 2015-04-07

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

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

清單 1. Job用法示例
Job job = new Job(“Job Name”){
protected IStatus run(IProgressMonitor monitor) {
				
		// 在這里添加你的任務(wù)代碼
		return Status.OK_STATUS;
	}
};
job.schedule(delayTime);

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

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

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

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

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

Eclipse中Job的實(shí)現(xiàn)

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

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

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

Eclipse中的UI線程

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

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

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

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

}

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

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

除主線程之外的所有線程都是非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ā)運(yùn)行

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

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

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

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

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

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

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

	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();
	}

	});
  • 延時(shí)執(zhí)行Job,避免無用的Job運(yùn)行

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

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

實(shí)際上,,Jface中就是通過延時(shí)執(zhí)行Job來實(shí)現(xiàn)這一功能的,。我們也可以自己實(shí)現(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);
	}
});

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

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

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

有 時(shí),我們需要對相關(guān)聯(lián)的Job一起處理,。例如需要同時(shí)取消這些Job,,或者等待所有這些Job結(jié)束。這時(shí)我們可以使用Job Family,。對于相關(guān)聯(lián)的Job,,我們可以將它們設(shè)置成同一個(gè)Job Family。我們需要重載Job的belongsTo方法以設(shè)置一個(gè)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進(jìn)行操作:

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ùn)行異常(例如程序沒有響應(yīng)),我們首先要確定是否發(fā)生了死鎖,。通過下面這些步驟,,我們可以確定是否死鎖以及死鎖的線程:

  • 在Eclipse中以Debug模式運(yùn)行程序
  • 執(zhí)行響應(yīng)的測試用例重現(xiàn)問題
  • 在Eclipse的Debug View中選中主線程(Thread[main]),選擇菜單Run->Suspend,。這時(shí)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)系,以便找出死鎖的原因,。我們找出死鎖的線程后就可以針對不同情況進(jìn)行處理:

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

Job使用中要注意的問題

  • 不 要在Job中使用Thread.sleep方法。如果你想要讓Job進(jìn)入睡眠狀態(tài),,最好用Job的sleep方法,。雖然,使用Thread.sleep和 Job的sleep方法達(dá)到的效果差不多,,但是它們實(shí)現(xiàn)的方式完全不同,,對系統(tǒng)的影響也不一樣。我們知道Eclipse中Job是由Eclipse的 JobManager來管理的,。如果我們調(diào)用Job的sleep方法,,JobManager會將Job轉(zhuǎn)入睡眠狀態(tài),與其對應(yīng)的線程也會重新放入線程池等 待運(yùn)行其他Job,。而如果我們在Job中直接調(diào)用Thread.sleep方法,,它會直接使運(yùn)行Job的線程進(jìn)入睡眠狀態(tài),其他Job就不可能重用這個(gè)線 程了,。同時(shí),,雖然運(yùn)行該Job的線程進(jìn)入了睡眠狀態(tài),,Job的狀態(tài)還是Running(運(yùn)行狀態(tài)),,我們也不能用Job的wakeup方法喚醒該Job了
  • Job 的取消。一般我們會直觀的認(rèn)為,一旦調(diào)用Job的cancel方法,,Job就會停止運(yùn)行,。實(shí)際上,這并不一定正確,,當(dāng)Job處于不同的狀態(tài)時(shí),,我們調(diào)用 Job的cancel方法所起的效果是不同的。當(dāng)Job在WAITING狀態(tài)和SLEEPING狀態(tài)時(shí),,一旦我們調(diào)用cancel方 法,,JobManager會將Job直接從等待運(yùn)行的隊(duì)列中刪除,Job不會再運(yùn)行了,,這時(shí)cancel方法會返回true,。但是如果Job正在運(yùn) 行,cancel方法調(diào)用并不會立即終止Job的運(yùn)行,,它只會設(shè)定一個(gè)標(biāo)志,,指明這個(gè)Job已經(jīng)被取消了。我們可以使用Job的run方法傳入的參數(shù) IProgressMonitor monitor,,這個(gè)參數(shù)的isCanceled方法會返回Job是否被取消的狀態(tài),。如果需要,我們必須在我們的代碼的適當(dāng)位置檢查Job是否被取消的標(biāo) 志,,作出適當(dāng)?shù)捻憫?yīng),。另外,由于調(diào)用Job的cancel方法不一定立即終止Job,,如果我們需要等待被取消的Job運(yùn)行完再執(zhí)行,,我們可以用如下代碼:
     if (!job.cancel())
    job.join();
  • Join方法的使用。由于join方法會導(dǎo)致一個(gè)線程等待另一個(gè)線程,,一旦等待線程中擁有一個(gè)被等待線程所需要的鎖,,就會產(chǎn)生死鎖。當(dāng)我們的線程中需要用到同步時(shí),,這種死鎖的情況非常容易出現(xiàn),,所以我們使用join時(shí)必須非常小心,盡量以其他方法替代,。
  • 避 免過時(shí)的Job造成的錯(cuò)誤,。由于我們啟動的線程并不一定是馬上執(zhí)行的,當(dāng)我們的Job開始運(yùn)行時(shí),,情況可能發(fā)生了變化,。我們在Job的處理代碼中要考慮到 這些情況。一種典型的情況是,,我們在啟動一個(gè)對話框或者初始化一個(gè)ViewPart時(shí),,我們會啟動一些 Job去完成一些數(shù)據(jù)讀取的工作,一旦數(shù)據(jù)讀取結(jié)束,我們會啟動新的UI Job更新相應(yīng)的UI,。有時(shí),,用戶在打開對話框或者View后,馬上關(guān)閉了該對話框或者View,。這時(shí)我們啟動的線程并沒有被中斷,,一旦在Job中再去更 新UI,就會出錯(cuò),。在我們的代碼中必須作相應(yīng)的處理,。所以,我們在線程中更新界面元素之前,,我們必須先檢查相應(yīng)的控件是否已經(jīng)被dispose了

結(jié)束語

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

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

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

參考資料

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多