摘要:相對于,并不是很讓人熟知,其實和很類似,只不過它有返回值,并且也沒有方法,而是有方法。接口類似于,兩者都是為那些其實例可能被另一個線程執行的類設計的。但是不會返回結果,并且無法拋出經過檢查的異常。
Callable
相對于Runnable,Callable并不是很讓人熟知,其實Callable和Runnable很類似,只不過它有返回值,并且也沒有run()方法,而是有call()方法。
public interface Callable{ V call() throw Exception; }
Callable 接口類似于 Runnable,兩者都是為那些其實例可能被另一個線程執行的類設計的。但是 Runnable 不會返回結果,并且無法拋出經過檢查的異常。
可以看到,返回的結果是以V泛型表示的,比如Callable
Future用來保存異步計算的結果,就是說之前用Callable標志的任務可以用Future來進行包裝,那為什么非要用Future呢,Callable自己運行然后用相應的類型來接收結果不就行了嗎?之所以要用到Future,有一下兩個原因:
Thread t = new Thread(..)用這個方法創建一個線程,必須要傳給一個Runnable的參數,而不能傳給它Callable
Future對象具有一系列的方法,比如它的get方法能夠被阻塞,直到計算完成;也可以在任務進行的過程中取消它。這些方法使得它更便利
FutureTask但是Future終究只是一個接口,而FutureTask包裝器不僅實現了Future接口,還實現了Runnable接口,這彌補上面的遺憾,使得它不僅能被Thread運行,還具有取消運行的特性,一個典型的使用FutureTask的例子就是:
Callablecalc = ...; FutureTask task = new FutureTask (calc); Thread t = new Thread(task); //這里是Runnable t.start; ... Integer result = task.get(); //這里是Future
住:FutureTask的兩個構造方法
FutureTask(Callable
task)
FutureTask(Runnable task,V result)
Demo一個計算指定目錄下具有指定關鍵字的文件數目的例子:
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<>(); // 用來保存所有的異步計算結果 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!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/64439.html
摘要:類提供了一些有用的方法在線程池中執行內的任務。在線程池提交任務后返回了一個對象,使用它可以知道任務的狀態和得到返回的執行結果。 Callable和Future出現的原因 創建線程的2種方式,一種是直接繼承Thread,另外一種就是實現Runnable接口。 這2種方式都有一個缺陷就是:在執行完任務之后無法獲取執行結果。 如果需要獲取執行結果,就必須通過共享變量或者使用線程通信的方式來達...
摘要:聲明了幾種方法,其中有一個就是傳入聲明了對具體的或者任務執行進行取消查詢結果獲取等方法。事實上,是接口的一個唯一實現類。使用示例第一種方式是使用繼承了的線程池中的方法,將直接提交創建。 創建線程的兩種方式 直接繼承 Thread 實現 Runnable 接口 這兩種方式都有一個缺點:在執行完成任務之后,無法直接獲取到最后的執行結果。如果需要獲取執行結果,就必須通過共享變量或線程通...
摘要:類被聲明在的內部類,并且為和。構造函數接受的整數值,并存儲在類變量中以備后用。該方法會創建固定的線程池,用于執行不同的任務,并且在結束時會返回一個實例。聲明的對象用于存儲對象,從而監控提交的任務。 showImg(https://segmentfault.com/img/remote/1460000013292810?w=1200&h=675); Callabl、Future、Exec...
摘要:使用進行并行編程在中進行并行編程最常用的方式是繼承類或者實現接口。從開始提供了和兩個接口,通過使用它們可以在任務執行完畢后得到執行結果。 使用Callable、Future進行并行編程 在Java中進行并行編程最常用的方式是繼承Thread類或者實現Runnable接口。這兩種方式的缺點是在任務完成后無法直接獲取執行結果,必須通過共享變量或線程間通信,使用起來很不方便。從Java 1....
摘要:本文首發于一世流云的專欄一模式簡介模式是多線程設計模式中的一種常見模式,它的主要作用就是異步地執行任務,并在需要的時候獲取結果。二中的模式在多線程基礎之模式中,我們曾經給出過模式的通用類關系圖。 showImg(https://segmentfault.com/img/bVbiwcx?w=1000&h=667); 本文首發于一世流云的專欄:https://segmentfault.co...
閱讀 1407·2021-11-08 13:14
閱讀 762·2021-09-23 11:31
閱讀 1052·2021-07-29 13:48
閱讀 2792·2019-08-29 12:29
閱讀 3387·2019-08-29 11:24
閱讀 1912·2019-08-26 12:02
閱讀 3709·2019-08-26 10:34
閱讀 3450·2019-08-23 17:07