摘要:相對于,并不是很讓人熟知,其實和很類似,只不過它有返回值,并且也沒有方法,而是有方法。接口類似于,兩者都是為那些其實例可能被另一個線程執(zhí)行的類設(shè)計的。但是不會返回結(jié)果,并且無法拋出經(jīng)過檢查的異常。
Callable
相對于Runnable,Callable并不是很讓人熟知,其實Callable和Runnable很類似,只不過它有返回值,并且也沒有run()方法,而是有call()方法。
public interface Callable{ V call() throw Exception; }
Callable 接口類似于 Runnable,兩者都是為那些其實例可能被另一個線程執(zhí)行的類設(shè)計的。但是 Runnable 不會返回結(jié)果,并且無法拋出經(jīng)過檢查的異常。
可以看到,返回的結(jié)果是以V泛型表示的,比如Callable
Future用來保存異步計算的結(jié)果,就是說之前用Callable標(biāo)志的任務(wù)可以用Future來進(jìn)行包裝,那為什么非要用Future呢,Callable自己運行然后用相應(yīng)的類型來接收結(jié)果不就行了嗎?之所以要用到Future,有一下兩個原因:
Thread t = new Thread(..)用這個方法創(chuàng)建一個線程,必須要傳給一個Runnable的參數(shù),而不能傳給它Callable
Future對象具有一系列的方法,比如它的get方法能夠被阻塞,直到計算完成;也可以在任務(wù)進(jìn)行的過程中取消它。這些方法使得它更便利
FutureTask但是Future終究只是一個接口,而FutureTask包裝器不僅實現(xiàn)了Future接口,還實現(xiàn)了Runnable接口,這彌補上面的遺憾,使得它不僅能被Thread運行,還具有取消運行的特性,一個典型的使用FutureTask的例子就是:
Callablecalc = ...; FutureTask task = new FutureTask (calc); Thread t = new Thread(task); //這里是Runnable t.start; ... Integer result = task.get(); //這里是Future
住:FutureTask的兩個構(gòu)造方法
FutureTask(Callable
task)
FutureTask(Runnable task,V result)
Demo一個計算指定目錄下具有指定關(guān)鍵字的文件數(shù)目的例子:
package future; import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import java.util.concurrent.Callable; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; public class MatchCounter implements Callable{ private File directory; private String keyword; private int count; public MatchCounter(File directory, String keyword) { this.directory = directory; this.keyword = keyword; } @Override public Integer call() throws Exception { count = 0; try { File[] files = directory.listFiles(); List > results = new ArrayList<>(); // 用來保存所有的異步計算結(jié)果 for (File file : files) { if (file.isDirectory()) { MatchCounter counter = new MatchCounter(file, keyword); FutureTask task = new FutureTask<>(counter); results.add(task); Thread t = new Thread(task); t.start(); } else { if (search(file)) { count++; } } } for (Future r : results) { count += r.get(); } } catch (InterruptedException e) { } return count; } public boolean search(File file) { try { Scanner in = new Scanner(file); boolean found = false; while (in.hasNextLine()) { String line = in.nextLine(); if (line.contains(keyword)) { found = true; } } return found; } catch (FileNotFoundException e) { e.printStackTrace(); } return false; } }
測試類:
package future; import java.io.File; import java.util.Scanner; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class FutureTest { public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.println("Enter starting directory:"); String d = in.nextLine(); System.out.println("Enter keyword:"); String keyword = in.nextLine(); MatchCounter counter = new MatchCounter(new File(d), keyword); FutureTasktask = new FutureTask<>(counter); new Thread(task).start(); try { System.out.println(task.get() + " matching files!"); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }
運行:
Enter starting directory: D:workspaceconcurrentsrc Enter keyword: future 2 matching files!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/64439.html
摘要:類提供了一些有用的方法在線程池中執(zhí)行內(nèi)的任務(wù)。在線程池提交任務(wù)后返回了一個對象,使用它可以知道任務(wù)的狀態(tài)和得到返回的執(zhí)行結(jié)果。 Callable和Future出現(xiàn)的原因 創(chuàng)建線程的2種方式,一種是直接繼承Thread,另外一種就是實現(xiàn)Runnable接口。 這2種方式都有一個缺陷就是:在執(zhí)行完任務(wù)之后無法獲取執(zhí)行結(jié)果。 如果需要獲取執(zhí)行結(jié)果,就必須通過共享變量或者使用線程通信的方式來達(dá)...
摘要:聲明了幾種方法,其中有一個就是傳入聲明了對具體的或者任務(wù)執(zhí)行進(jìn)行取消查詢結(jié)果獲取等方法。事實上,是接口的一個唯一實現(xiàn)類。使用示例第一種方式是使用繼承了的線程池中的方法,將直接提交創(chuàng)建。 創(chuàng)建線程的兩種方式 直接繼承 Thread 實現(xiàn) Runnable 接口 這兩種方式都有一個缺點:在執(zhí)行完成任務(wù)之后,無法直接獲取到最后的執(zhí)行結(jié)果。如果需要獲取執(zhí)行結(jié)果,就必須通過共享變量或線程通...
摘要:類被聲明在的內(nèi)部類,并且為和。構(gòu)造函數(shù)接受的整數(shù)值,并存儲在類變量中以備后用。該方法會創(chuàng)建固定的線程池,用于執(zhí)行不同的任務(wù),并且在結(jié)束時會返回一個實例。聲明的對象用于存儲對象,從而監(jiān)控提交的任務(wù)。 showImg(https://segmentfault.com/img/remote/1460000013292810?w=1200&h=675); Callabl、Future、Exec...
摘要:使用進(jìn)行并行編程在中進(jìn)行并行編程最常用的方式是繼承類或者實現(xiàn)接口。從開始提供了和兩個接口,通過使用它們可以在任務(wù)執(zhí)行完畢后得到執(zhí)行結(jié)果。 使用Callable、Future進(jìn)行并行編程 在Java中進(jìn)行并行編程最常用的方式是繼承Thread類或者實現(xiàn)Runnable接口。這兩種方式的缺點是在任務(wù)完成后無法直接獲取執(zhí)行結(jié)果,必須通過共享變量或線程間通信,使用起來很不方便。從Java 1....
摘要:本文首發(fā)于一世流云的專欄一模式簡介模式是多線程設(shè)計模式中的一種常見模式,它的主要作用就是異步地執(zhí)行任務(wù),并在需要的時候獲取結(jié)果。二中的模式在多線程基礎(chǔ)之模式中,我們曾經(jīng)給出過模式的通用類關(guān)系圖。 showImg(https://segmentfault.com/img/bVbiwcx?w=1000&h=667); 本文首發(fā)于一世流云的專欄:https://segmentfault.co...
閱讀 1395·2021-11-08 13:14
閱讀 747·2021-09-23 11:31
閱讀 1038·2021-07-29 13:48
閱讀 2781·2019-08-29 12:29
閱讀 3371·2019-08-29 11:24
閱讀 1899·2019-08-26 12:02
閱讀 3689·2019-08-26 10:34
閱讀 3435·2019-08-23 17:07