自定義FutureTask的實(shí)現(xiàn)方法

本篇內(nèi)容主要講解“自定義FutureTask的實(shí)現(xiàn)方法”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“自定義FutureTask的實(shí)現(xiàn)方法”吧!

創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、白城網(wǎng)絡(luò)推廣、小程序開(kāi)發(fā)、白城網(wǎng)絡(luò)營(yíng)銷、白城企業(yè)策劃、白城品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供白城建站搭建服務(wù),24小時(shí)服務(wù)熱線:18982081108,官方網(wǎng)址:bm7419.com

FutureTask

FutureTask是Future的實(shí)現(xiàn),用來(lái)異步任務(wù)的獲取結(jié)果,可以啟動(dòng)和取消異步任務(wù),查詢異步任務(wù)是否計(jì)算結(jié)束以及獲取最終的異步任務(wù)的結(jié)果。通過(guò)get()方法來(lái)獲取異步任務(wù)的結(jié)果,但是會(huì)阻塞當(dāng)前線程直至異步任務(wù)執(zhí)行結(jié)束。一旦任務(wù)執(zhí)行結(jié)束,任務(wù)不能重新啟動(dòng)或取消,除非調(diào)用runAndReset()方法。

代碼示例:

public class ThreadTest {

  public static void main(String[] args) throws Exception {

    Callable<String> myCallable = new MyCallableThread();
    FutureTask<String> futureTask = new FutureTask<>(myCallable);
    Thread myCallableThread = new Thread(futureTask);
    myCallableThread.setName("MyThread-implements-Callable-test");
    myCallableThread.start();
    System.out.println("Run by Thread:" + futureTask.get());

    //通過(guò)線程池執(zhí)行
    ExecutorService executorService = Executors.newCachedThreadPool();
    executorService.submit(futureTask);
    executorService.shutdown();
    System.out.println("Run by ExecutorService:" + futureTask.get());
  }
}

class MyCallableThread implements Callable<String> {

  @Override
  public String call() throws Exception {
    return Thread.currentThread().getName();
  }
}

實(shí)現(xiàn)一個(gè)自己的FutureTask

根據(jù)FutureTask核心原理,要實(shí)現(xiàn)一個(gè)FutureTask必須滿足以下方面:

  • 需要泛型定義用以返回結(jié)果類型

  • 需要一個(gè)callable對(duì)象,在構(gòu)造方法中傳入

  • 需要實(shí)現(xiàn)runnable接口,在run方法中實(shí)現(xiàn)具體結(jié)果計(jì)算

  • 需要一個(gè)公開(kāi)的get方法來(lái)獲取結(jié)果

  • 如果線程沒(méi)有執(zhí)行完,則調(diào)用get方法的線程需要進(jìn)入等待隊(duì)列

  • 需要一個(gè)字段記錄線程執(zhí)行的狀態(tài)

  • 需要一個(gè)等待隊(duì)列存儲(chǔ)等待結(jié)果的線程

代碼示例:

/**
 * 1. 泛型定義
 * 2. 構(gòu)造方法 callable
 * 3. 實(shí)現(xiàn)了runnable
 * 4. get方法返回callable執(zhí)行結(jié)果
 * 5. get方法有阻塞的效果(未執(zhí)行結(jié)束的話)
 */
public class MyFutureTask<T> implements Runnable {

  // 程序執(zhí)行的結(jié)果
  private T result;

  // 要執(zhí)行的任務(wù)
  private Callable<T> callable;

  // 任務(wù)運(yùn)行的狀態(tài)
  private volatile int state = NEW;

  // 任務(wù)運(yùn)行的狀態(tài)值
  private static final int NEW = 0;
  private static final int RUNNING = 1;
  private static final int FINISHED = 2;

  // 獲取結(jié)果的線程等待隊(duì)列
  LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue<>(100);

  // 執(zhí)行當(dāng)前FutureTask的線程,用CAS進(jìn)行爭(zhēng)搶
  AtomicReference<Thread> runner = new AtomicReference<>();

  public MyFutureTask(Callable<T> task) {
    this.callable = task;
  }

  @Override
  public void run() {
    // 判斷當(dāng)前對(duì)象的狀態(tài),如果是New且搶鎖成功就執(zhí)行
    if (state != NEW || !runner.compareAndSet(null, Thread.currentThread())) return;
    state = RUNNING;
    try {
      result = callable.call();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      state = FINISHED;
    }

    // 方法執(zhí)行完,喚醒所有線程
    while (true) {
      Thread waiterThread = waiters.poll();
      if (waiterThread == null) break;
      LockSupport.unpark(waiterThread);
    }
  }

  public T get() {
    // 如果狀態(tài)不是FINISHED,則進(jìn)入等待隊(duì)列
    if (state != FINISHED) {
      waiters.offer(Thread.currentThread());
    }
    while (state != FINISHED) {
      LockSupport.park();
    }
    return result;
  }
}

// MyFutureTask 測(cè)試
public class FutureTaskTest {
  public static void main(String[] args) {

    Callable<String> myCallable = new MyCallableThread();
    MyFutureTask<String> futureTask = new MyFutureTask<>(myCallable);
    Thread myCallableThread = new Thread(futureTask);
    myCallableThread.setName("MyFutureTask-test");
    myCallableThread.start();
    System.out.println("Run by Thread:" + futureTask.get());
  }
}

class MyCallableThread implements Callable<String> {

  @Override
  public String call() throws Exception {
    return Thread.currentThread().getName();
  }
}

到此,相信大家對(duì)“自定義FutureTask的實(shí)現(xiàn)方法”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

文章題目:自定義FutureTask的實(shí)現(xiàn)方法
標(biāo)題路徑:http://bm7419.com/article28/psccjp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、網(wǎng)站收錄、網(wǎng)站設(shè)計(jì)、網(wǎng)站排名、ChatGPT標(biāo)簽優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化