欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java多線程編程同步器Future和FutureTask解析及代碼示例

 更新時(shí)間:2017年11月20日 14:24:12   作者:zheng12tian  
這篇文章主要介紹了java多線程編程同步器Future和FutureTask解析及代碼示例,對(duì)二者進(jìn)行了詳細(xì)介紹,分析了future的源碼,最后展示了相關(guān)實(shí)例代碼,具有一定參考價(jià)值 ,需要的朋友可以了解下。

publicinterfaceFuture<V>Future表示異步計(jì)算的結(jié)果。它提供了檢查計(jì)算是否完成的方法,以等待計(jì)算的完成,并獲取計(jì)算的結(jié)果。計(jì)算完成后只能使用get方法來(lái)獲取結(jié)果,如有必要,計(jì)算完成前可以阻塞此方法。取消則由cancel方法來(lái)執(zhí)行。還提供了其他方法,以確定任務(wù)是正常完成還是被取消了。一旦計(jì)算完成,就不能再取消計(jì)算。如果為了可取消性而使用Future但又不提供可用的結(jié)果,則可以聲明Future<?>形式類型、并返回null作為底層任務(wù)的結(jié)果。

Future主要定義了5個(gè)方法:

1)booleancancel(booleanmayInterruptIfRunning):試圖取消對(duì)此任務(wù)的執(zhí)行。如果任務(wù)已完成、或已取消,或者由于某些其他原因而無(wú)法取消,則此嘗試將失敗。當(dāng)調(diào)用cancel時(shí),如果調(diào)用成功,而此任務(wù)尚未啟動(dòng),則此任務(wù)將永不運(yùn)行。如果任務(wù)已經(jīng)啟動(dòng),則mayInterruptIfRunning參數(shù)確定是否應(yīng)該以試圖停止任務(wù)的方式來(lái)中斷執(zhí)行此任務(wù)的線程。此方法返回后,對(duì)isDone()的后續(xù)調(diào)用將始終返回true。如果此方法返回true,則對(duì)isCancelled()的后續(xù)調(diào)用將始終返回true。

2)booleanisCancelled():如果在任務(wù)正常完成前將其取消,則返回true。

3)booleanisDone():如果任務(wù)已完成,則返回true??赡苡捎谡=K止、異?;蛉∠瓿?,在所有這些情況中,此方法都將返回true。

4)Vget()throwsInterruptedException,ExecutionException:如有必要,等待計(jì)算完成,然后獲取其結(jié)果。

5)Vget(longtimeout,TimeUnitunit)throwsInterruptedException,ExecutionException,TimeoutException:如有必要,最多等待為使計(jì)算完成所給定的時(shí)間之后,獲取其結(jié)果(如果結(jié)果可用)。

Future<V>接口

Future<V>接口是用來(lái)獲取異步計(jì)算結(jié)果的,說(shuō)白了就是對(duì)具體的Runnable或者Callable對(duì)象任務(wù)執(zhí)行的結(jié)果進(jìn)行獲取(get()),取消(cancel()),判斷是否完成等操作。我們看看Future接口的源碼:

public interface Future<V> { 
 boolean cancel(boolean mayInterruptIfRunning); 
 boolean isCancelled(); 
 boolean isDone(); 
 V get() throws InterruptedException, ExecutionException; 
 V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; 
} 

方法解析:

Vget():獲取異步執(zhí)行的結(jié)果,如果沒(méi)有結(jié)果可用,此方法會(huì)阻塞直到異步計(jì)算完成。

Vget(Longtimeout,TimeUnitunit):獲取異步執(zhí)行結(jié)果,如果沒(méi)有結(jié)果可用,此方法會(huì)阻塞,但是會(huì)有時(shí)間限制,如果阻塞時(shí)間超過(guò)設(shè)定的timeout時(shí)間,該方法將拋出異常。

booleanisDone():如果任務(wù)執(zhí)行結(jié)束,無(wú)論是正常結(jié)束或是中途取消還是發(fā)生異常,都返回true。

booleanisCanceller():如果任務(wù)完成前被取消,則返回true。

booleancancel(booleanmayInterruptRunning):如果任務(wù)還沒(méi)開(kāi)始,執(zhí)行cancel(...)方法將返回false;如果任務(wù)已經(jīng)啟動(dòng),執(zhí)行cancel(true)方法將以中斷執(zhí)行此任務(wù)線程的方式來(lái)試圖停止任務(wù),如果停止成功,返回true;當(dāng)任務(wù)已經(jīng)啟動(dòng),執(zhí)行cancel(false)方法將不會(huì)對(duì)正在執(zhí)行的任務(wù)線程產(chǎn)生影響(讓線程正常執(zhí)行到完成),此時(shí)返回false;當(dāng)任務(wù)已經(jīng)完成,執(zhí)行cancel(...)方法將返回false。mayInterruptRunning參數(shù)表示是否中斷執(zhí)行中的線程。

通過(guò)方法分析我們也知道實(shí)際上Future提供了3種功能:(1)能夠中斷執(zhí)行中的任務(wù)(2)判斷任務(wù)是否執(zhí)行完成(3)獲取任務(wù)執(zhí)行完成后額結(jié)果。

但是我們必須明白Future只是一個(gè)接口,我們無(wú)法直接創(chuàng)建對(duì)象,因此就需要其實(shí)現(xiàn)類FutureTask登場(chǎng)啦。

FutureTask類

FutureTask可用于異步獲取執(zhí)行結(jié)果或取消執(zhí)行任務(wù)的場(chǎng)景。通過(guò)傳入Runnable或者Callable的任務(wù)給FutureTask,直接調(diào)用其run方法或者放入線程池執(zhí)行,之后可以在外部通過(guò)FutureTask的get方法異步獲取執(zhí)行結(jié)果,因此,F(xiàn)utureTask非常適合用于耗時(shí)的計(jì)算,主線程可以在完成自己的任務(wù)后,再去獲取結(jié)果。另外,F(xiàn)utureTask還可以確保即使調(diào)用了多次run方法,它都只會(huì)執(zhí)行一次Runnable或者Callable任務(wù),或者通過(guò)cancel取消FutureTask的執(zhí)行等。

我們來(lái)看看FutureTask的實(shí)現(xiàn)

public class FutureTask<V> implements RunnableFuture<V> { 

FutureTask類實(shí)現(xiàn)了RunnableFuture接口,我們看一下RunnableFuture接口的實(shí)現(xiàn):

public interface RunnableFuture<V> extends Runnable, Future<V> { 
 void run(); 
} 

分析:FutureTask除了實(shí)現(xiàn)了Future接口外還實(shí)現(xiàn)了Runnable接口,因此FutureTask也可以直接提交給Executor執(zhí)行。當(dāng)然也可以調(diào)用線程直接執(zhí)行(FutureTask.run())。接下來(lái)我們根據(jù)FutureTask.run()的執(zhí)行時(shí)機(jī)來(lái)分析其所處的3種狀態(tài):

(1)未啟動(dòng),F(xiàn)utureTask.run()方法還沒(méi)有被執(zhí)行之前,F(xiàn)utureTask處于未啟動(dòng)狀態(tài),當(dāng)創(chuàng)建一個(gè)FutureTask,而且沒(méi)有執(zhí)行FutureTask.run()方法前,這個(gè)FutureTask也處于未啟動(dòng)狀態(tài)。

(2)已啟動(dòng),F(xiàn)utureTask.run()被執(zhí)行的過(guò)程中,F(xiàn)utureTask處于已啟動(dòng)狀態(tài)。

(3)已完成,F(xiàn)utureTask.run()方法執(zhí)行完正常結(jié)束,或者被取消或者拋出異常而結(jié)束,F(xiàn)utureTask都處于完成狀態(tài)。

FutureTask類是Future的一個(gè)實(shí)現(xiàn),并實(shí)現(xiàn)了Runnable,所以可通過(guò)Excutor(線程池)來(lái)執(zhí)行。也可傳遞給Thread對(duì)象執(zhí)行。如果在主線程中需要執(zhí)行比較耗時(shí)的操作時(shí),但又不想阻塞主線程時(shí),可以把這些作業(yè)交給Future對(duì)象在后臺(tái)完成,當(dāng)主線程將來(lái)需要時(shí),就可以通過(guò)Future對(duì)象獲得后臺(tái)作業(yè)的計(jì)算結(jié)果或者執(zhí)行狀態(tài)。下面的例子模擬一個(gè)會(huì)計(jì)算賬的過(guò)程,主線程已經(jīng)獲得其他帳戶的總額了,為了不讓主線程等待PrivateAccount類的計(jì)算結(jié)果的返回而啟用新的線程去處理,并使用FutureTask對(duì)象來(lái)監(jiān)控,這樣,主線程還可以繼續(xù)做其他事情,最后需要計(jì)算總額的時(shí)候再嘗試去獲得privateAccount的信息。

package test;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
 *
 * @author Administrator
 *
 */
@SuppressWarnings("all")
public class FutureTaskDemo {
	public static void main(String[] args) {
		// 初始化一個(gè)Callable對(duì)象和FutureTask對(duì)象
		Callable pAccount = new PrivateAccount();
		FutureTask futureTask = new FutureTask(pAccount);
		// 使用futureTask創(chuàng)建一個(gè)線程
		Thread pAccountThread = new Thread(futureTask);
		System.out.println("futureTask線程現(xiàn)在開(kāi)始啟動(dòng),啟動(dòng)時(shí)間為:" + System.nanoTime());
		pAccountThread.start();
		System.out.println("主線程開(kāi)始執(zhí)行其他任務(wù)");
		// 從其他賬戶獲取總金額
		int totalMoney = new Random().nextint(100000);
		System.out.println("現(xiàn)在你在其他賬戶中的總金額為" + totalMoney);
		System.out.println("等待私有賬戶總金額統(tǒng)計(jì)完畢...");
		// 測(cè)試后臺(tái)的計(jì)算線程是否完成,如果未完成則等待
		while (!futureTask.isDone()) {
			try {
				Thread.sleep(500);
				System.out.println("私有賬戶計(jì)算未完成繼續(xù)等待...");
			}
			catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("futureTask線程計(jì)算完畢,此時(shí)時(shí)間為" + System.nanoTime());
		Integer privateAccountMoney = null;
		try {
			privateAccountMoney = (Integer) futureTask.get();
		}
		catch (InterruptedException e) {
			e.printStackTrace();
		}
		catch (ExecutionException e) {
			e.printStackTrace();
		}
		System.out.println("您現(xiàn)在的總金額為:" + totalMoney + privateAccountMoney.intValue());
	}
}
@SuppressWarnings("all")
class PrivateAccount implements Callable {
	Integer totalMoney;
	@Override
		public Object call() throws Exception {
		Thread.sleep(5000);
		totalMoney = new Integer(new Random().nextint(10000));
		System.out.println("您當(dāng)前有" + totalMoney + "在您的私有賬戶中");
		return totalMoney;
	}
}

運(yùn)行結(jié)果 

futureTask線程現(xiàn)在開(kāi)始啟動(dòng),啟動(dòng)時(shí)間為:3098040622063 
主線程開(kāi)始執(zhí)行其他任務(wù) 
現(xiàn)在你在其他賬戶中的總金額為56983 
等待私有賬戶總金額統(tǒng)計(jì)完畢... 
私有賬戶計(jì)算未完成繼續(xù)等待... 
私有賬戶計(jì)算未完成繼續(xù)等待... 
私有賬戶計(jì)算未完成繼續(xù)等待... 
私有賬戶計(jì)算未完成繼續(xù)等待... 
私有賬戶計(jì)算未完成繼續(xù)等待... 
私有賬戶計(jì)算未完成繼續(xù)等待... 
私有賬戶計(jì)算未完成繼續(xù)等待... 
私有賬戶計(jì)算未完成繼續(xù)等待... 
私有賬戶計(jì)算未完成繼續(xù)等待... 
您當(dāng)前有3345在您的私有賬戶中 
私有賬戶計(jì)算未完成繼續(xù)等待... 
futureTask線程計(jì)算完畢,此時(shí)時(shí)間為3103072404138 
您現(xiàn)在的總金額為:569833345

總結(jié)

以上就是本文關(guān)于java多線程編程同步器Future和FutureTask解析及代碼示例的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:

Java多線程之顯示鎖和內(nèi)置鎖總結(jié)詳解

Java多線程中斷機(jī)制三種方法及示例

java多線程編程實(shí)例

如有不足之處,歡迎留言指出。

相關(guān)文章

  • 詳解Java中l(wèi)og4j.properties配置與加載應(yīng)用

    詳解Java中l(wèi)og4j.properties配置與加載應(yīng)用

    這篇文章主要介紹了 log4j.properties配置與加載應(yīng)用的相關(guān)資料,需要的朋友可以參考下
    2018-02-02
  • Java中的 VO,BO,DO 對(duì)象命名問(wèn)題小結(jié)

    Java中的 VO,BO,DO 對(duì)象命名問(wèn)題小結(jié)

    本文講解VO,BO,DO 的作用以及如何使用,分析了如何消除三者之間重復(fù)的代碼,同樣結(jié)合現(xiàn)實(shí)生活中領(lǐng)導(dǎo)配秘書來(lái)類比講解,對(duì)Java  VO  對(duì)象命名相關(guān)知識(shí)感興趣的朋友一起看看吧
    2024-01-01
  • 輕松搞定SpringBoot JPA使用配置過(guò)程詳解

    輕松搞定SpringBoot JPA使用配置過(guò)程詳解

    Spring Boot是由Pivotal團(tuán)隊(duì)提供的全新框架,該框架使用了特定的方式來(lái)進(jìn)行配置,它默認(rèn)配置了很多框架的使用方式,就像 Maven整合了所有的Jar包,Spring Boot 整合了所有的框架
    2021-06-06
  • Java 反轉(zhuǎn)帶頭結(jié)點(diǎn)的單鏈表并顯示輸出的實(shí)現(xiàn)過(guò)程

    Java 反轉(zhuǎn)帶頭結(jié)點(diǎn)的單鏈表并顯示輸出的實(shí)現(xiàn)過(guò)程

    這篇文章主要介紹了Java 反轉(zhuǎn)帶頭結(jié)點(diǎn)的單鏈表并顯示輸出,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-11-11
  • spring boot集成mongodb的增刪改查的示例代碼

    spring boot集成mongodb的增刪改查的示例代碼

    這篇文章主要介紹了spring boot集成mongodb的增刪改查的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Java Spring動(dòng)態(tài)生成Mysql存儲(chǔ)過(guò)程詳解

    Java Spring動(dòng)態(tài)生成Mysql存儲(chǔ)過(guò)程詳解

    這篇文章主要介紹了Java Spring動(dòng)態(tài)生成Mysql存儲(chǔ)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • springboot解決java.lang.ArrayStoreException異常

    springboot解決java.lang.ArrayStoreException異常

    這篇文章介紹了springboot解決java.lang.ArrayStoreException異常的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12
  • IO流:java中解碼和編碼出現(xiàn)亂碼說(shuō)明以及代碼實(shí)現(xiàn)方法

    IO流:java中解碼和編碼出現(xiàn)亂碼說(shuō)明以及代碼實(shí)現(xiàn)方法

    最近使用Java編寫一些讀取文件的小工具的時(shí)候,經(jīng)常與IO流打交道,但是自己對(duì)IO流的理解不是特別深刻,趁機(jī)整理下,這篇文章主要給大家介紹了關(guān)于IO流:java中解碼和編碼出現(xiàn)亂碼說(shuō)明以及代碼實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • Java 坐標(biāo)系相互轉(zhuǎn)換方式

    Java 坐標(biāo)系相互轉(zhuǎn)換方式

    這篇文章主要介紹了Java中的坐標(biāo)系相互轉(zhuǎn)換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 經(jīng)典再現(xiàn) 基于JAVA平臺(tái)開(kāi)發(fā)坦克大戰(zhàn)游戲

    經(jīng)典再現(xiàn) 基于JAVA平臺(tái)開(kāi)發(fā)坦克大戰(zhàn)游戲

    經(jīng)典再現(xiàn),這篇文章主要介紹了基于JAVA平臺(tái)開(kāi)發(fā)坦克大戰(zhàn)游戲的相關(guān)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-06-06

最新評(píng)論