日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747


 

憑據(jù)管理

在日常生活中,我們經(jīng)常會(huì)遇到一種情況,就是在我們提出需求之后,由于服務(wù)者還沒(méi)有準(zhǔn)備好對(duì)應(yīng)的實(shí)物交付給我們的時(shí)候,就會(huì)先給我們一張憑據(jù),等到雙方約定的時(shí)間到了之后,我們帶著這個(gè)憑據(jù)就可以去獲取到我們想要的東西。例如在一個(gè)蛋糕店里我們定了一個(gè)蛋糕,店長(zhǎng)給了我們一個(gè)憑據(jù),然后在約定的時(shí)間我們?nèi)サ案獾曛腥∽呶覀兌ǖ牡案狻_@樣我們不需要在店里等待,而是去完成我們的其他工作。

在程序開(kāi)發(fā)中假設(shè)有一個(gè)任務(wù)執(zhí)行的時(shí)間比較長(zhǎng),通常需要我們等待這個(gè)任務(wù)完成之后才能進(jìn)行后續(xù)的任務(wù),這個(gè)時(shí)候服務(wù)的調(diào)用者就會(huì)一直等待。而我們利用上面的介紹的憑據(jù)的方式就完全可以解決調(diào)用者等待的問(wèn)題。也就是JAVA中常說(shuō)的Future模式。下面我們就來(lái)看看關(guān)于Java中的Future模式。

Future設(shè)計(jì)模式

Future設(shè)計(jì)模式是從JDK1.5開(kāi)始出現(xiàn)的,在我們實(shí)現(xiàn)多線程操作的時(shí)候有常用的兩種方式,一種是實(shí)現(xiàn)Runnbale接口,一種是繼承Thread類,而我們不是太常用的一種方式就是Call接口的方式,這種方式就是類似于Future模式。其實(shí)現(xiàn)類圖如下。


 

下面我們就來(lái)看看Future設(shè)計(jì)模式的具體實(shí)現(xiàn)方式。

接口邏輯定義

Future接口

根據(jù)之前的分析我們的票據(jù)應(yīng)當(dāng)具有兩個(gè)功能,一個(gè)功能是可以通過(guò)它獲取到我們想要的結(jié)果,另一個(gè)功能就是通過(guò)它我們可以知道我們想要的蛋糕是否制作完成。如下所示。

public interface Future {// 用于返回計(jì)算之后的結(jié)果T get() throws InterruptedException;// 用于判斷任務(wù)是否正常執(zhí)行boolean done();

FutureService接口

FutureService 的主要作用就是任務(wù)的提交,而提交任務(wù)的方式有兩種,一種是不需要返回值的,一種是需要返回值的。代碼如下。

public interface FutureService {// 提交不需要進(jìn)行返回的任務(wù)的時(shí)候 Future的get方法返回為空Future submit(Runnable runnable);// 提交需要返回值的任務(wù)的時(shí)候 Future的get方法就是獲取到返回值Future submit(Tasktask,IN input);// 靜態(tài)方法獲取到實(shí)現(xiàn)實(shí)例對(duì)象static FutureService newServcie(){return new FutureServiceImpl<>();

Task接口

有了票據(jù),有了服務(wù)人員,接下來(lái)就是需要有我們需要完成的任務(wù)是什么,而Task就是用來(lái)提供給調(diào)用者實(shí)現(xiàn)計(jì)算邏輯的任務(wù)。可以接受一個(gè)參數(shù)并且返回最后的結(jié)果。有點(diǎn)類似于Callable接口

@FunctionalInterfacepublic interface Task {//給定一個(gè)參數(shù)經(jīng)過(guò)計(jì)算之后得到一個(gè)結(jié)果OUT get(IN input);Future程序?qū)崿F(xiàn)

Future接口實(shí)現(xiàn)

會(huì)發(fā)現(xiàn)這個(gè)接口實(shí)現(xiàn)除了實(shí)現(xiàn)Future接口的兩個(gè)方法之外還增加了一個(gè)finish的方法,用來(lái)完成任務(wù)通知操作。

public class FutureTask implements Future {// 返回結(jié)果private T result;//任務(wù)是否完成private boolean isDone = false;// 對(duì)象鎖private final Object LOCK = new Object();@Overridepublic T get() throws InterruptedException {synchronized (LOCK){//當(dāng)任務(wù)還沒(méi)有完成的時(shí)候,調(diào)用get方法會(huì)被掛起進(jìn)入阻塞等待while (!isDone){LOCK.wait();// 返回計(jì)算結(jié)果return result;protected void finish(T result){synchronized (LOCK){//balking 設(shè)計(jì)模式if (isDone){return;// 計(jì)算完成,為result指定結(jié)果,并且將isDone設(shè)置為true,同時(shí)喚起等待中的線程this.result = result;this.isDone = true;LOCK.notifyAll();@Overridepublic boolean done() {return isDone;

在FutureTask中使用了線程間的通信wait和notifyAll,當(dāng)任務(wù)沒(méi)有完成之前通過(guò)get方法獲取接口,調(diào)用方會(huì)進(jìn)入到阻塞狀態(tài),直到任務(wù)完成之后收到線程喚醒,finish方法接收到任務(wù)完成的通知,然后喚醒因?yàn)檎{(diào)用了get方法而進(jìn)入阻塞的線程。

FutureService實(shí)現(xiàn)

public class FutureServiceImpl implements FutureService {private final static String FUTURE_THREAD_PREFIX = "FUTURE-";private final AtomicInteger nextCounter = new AtomicInteger(0);private String getNextName(){return FUTURE_THREAD_PREFIX+nextCounter.getAndIncrement();@Overridepublic Future submit(Runnable runnable) {final FutureTask future = new FutureTask<>();new Thread(()->{runnable.run();// 任務(wù)執(zhí)行結(jié)束之后將null作為參數(shù)返回future.finish(null);},getNextName()).start();return future;@Overridepublic Future submit(Task task, IN input) {final FutureTask future = new FutureTask<>();new Thread(()->{OUT result = task.get(input);// 任務(wù)執(zhí)行結(jié)束之后,將真實(shí)的結(jié)果通過(guò)finish的方式傳遞給futurefuture.finish(result);},getNextName()).start();return future;Future設(shè)計(jì)模式測(cè)試

這里我們提交一個(gè)沒(méi)有返回值的任務(wù),代碼如下,

public class FutureTest {public static void main(String[] args) throws InterruptedException {FutureService service = FutureService.newServcie();Future future = service.submit(()->{try {TimeUnit.SECONDS.sleep(10);} catch (InterruptedException e) {e.printStackTrace();System.out.println("任務(wù)完成!");future.get();

提交一個(gè)有返回值的任務(wù)

public class FutureTest {public static void main(String[] args) throws InterruptedException {FutureService service = FutureService.newServcie();Future future = service.submit(input->{try {TimeUnit.SECONDS.sleep(10);} catch (InterruptedException e) {e.printStackTrace();return input.length();},"Hello");System.out.println(future.get());升級(jí)獲取結(jié)果的方法

從上面兩個(gè)測(cè)試的返回結(jié)果來(lái)看,如果我們調(diào)用了future的get方法,那么我們的程序就會(huì)進(jìn)入到阻塞的狀態(tài),這個(gè)操作與我們的預(yù)期不太相符合,這個(gè)也是整個(gè)的Future模式一直存在的問(wèn)題。那么我們?nèi)绾稳ジ倪M(jìn)這個(gè)獲取get方法等待的問(wèn)題呢?這就引入了一個(gè)Callback的機(jī)制。代碼如下

@Overridepublic Future submit(Task task, IN input, Callback callback) {final FutureTask future = new FutureTask<>();new Thread(()->{OUT result = task.get(input);// 任務(wù)執(zhí)行結(jié)束之后,將真實(shí)的結(jié)果通過(guò)finish的方式傳遞給futurefuture.finish(result);if (null!=callback){callback.call(result);},getNextName()).start();return future;

測(cè)試效果,會(huì)發(fā)現(xiàn)我們課可以不使用get方法就可以完成執(zhí)行結(jié)果的獲取。

public class FutureTest {public static void main(String[] args) throws InterruptedException {FutureService service = FutureService.newServcie();service.submit(input->{try {TimeUnit.SECONDS.sleep(10);} catch (InterruptedException e) {e.printStackTrace();return input.length();},"Hello",System.out::println);總結(jié)

在之前的分享中很多的地方我們都提到了Future設(shè)計(jì)模式,通過(guò)這篇文章我們也進(jìn)一步的了解了關(guān)于Future設(shè)計(jì)模式的思想。其核心思想就是模擬了一個(gè)憑據(jù)場(chǎng)景,通過(guò)這種方式來(lái)實(shí)現(xiàn)對(duì)CPU的高效利用。當(dāng)然這里我們給出的只是一個(gè)基礎(chǔ)演示版本,其中的存在的問(wèn)題還有很多,有興趣的讀者可以自己思考相關(guān)內(nèi)容的優(yōu)化。

分享到:
標(biāo)簽:Future
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定