我有一個 for 回圈,我在其中呼叫 db 以獲取學生的一些值。現在 for 回圈需要很多時間。所以想用帶有未來物件的執行器服務替換它。在函式開始時,我使用executor.submit()方法呼叫 db。我只是不確定如何為那個特定的學生找到回傳的未來物件,我可以將其用于進一步的步驟。請在下面找到代碼
下面的函式是從一個 for 回圈中呼叫的,自從被每個學生呼叫以來,總體上需要很多時間:
public void getDbDetails(String student){
//calling db
if(dbDetails.studentName = "XYZ"){
//function based on student ID
}
}
使用執行器框架:
public void getStudentData(List<String> students){
final List<Future<?>> futures = new ArrayList<>();
for(String student: students){
Future<?> future = executor.submit(() ->{
//db call
});
futures.add(future);
}
}
public void getDbDetails(String student){
//In this case how would i know whether future has returned details for this particular student??
if(dbDetails.studentName = "XYZ"){
//function based on student ID
}
}
是否可以使用future.get()和創建基于來自未來物件的 studentId 的地圖,然后在函式getDbDetails()中使用該地圖來獲取特定的學生資訊,如果未來沒有回傳任何內容,那么使用Thread.wait();?這種方法是否正確或其他任何方法都可以用作最佳解決方案?
uj5u.com熱心網友回復:
主要問題是您的任務回傳值是void. 相反,您應該定義一個Callable回傳值的 a 。
一些未經測驗的代碼的草稿:
public class StudentNameLookup implements Callable < String >
{
private String studentId ;
public StudentNameLookup ( String studentId )
{
this.studentId = studentId ;
}
public String call()
{
String studentName ;
// … DB call, passing `this.studentId`, returning a value stored in `studentName` local var.
return studentName ;
}
}
在 Java 16 中,為了簡潔起見,我們可以使用記錄。
public record StudentNameLookup ( String studentId ) implements Callable < String >
{
public String call()
{
String studentName ;
// … DB call, passing `this.studentId`, returning a value stored in `studentName` local var.
return studentName ;
}
}
出于個人喜好,我會建立一個任務串列。
List < Callable < String > > tasks = new ArrayList<>();
for( String studentId : studentIds )
{
Callable < String > task = new StudentNameLookup( studentId ) ;
tasks.add( task ) ;
}
將所有任務提交給執行器服務。你會得到一份期貨清單。
您的期貨的引數化型別(尖括號)將是您在Callable.
ExecutorService es = Executors. … ;
List < Future < String > > futures = es.invokeAll( tasks ) ;
然后做通常的執行器服務作業。關閉,等待終止。之后,您就知道所有提交的任務都已處理完畢。
回圈你的期貨清單。測驗每個未來以查看它是否成功,然后檢索其結果。
String studentName = future.get() ;
閱讀 Javadoc 并在 Stack Overflow 上搜索樣板檔案。
如果您想回傳學生 ID 以及檢索到的學生姓名,請更改您的回傳型別。與其回傳一個單純的String,不如回傳一個你發明的型別的物件,一個包含 id 和 name 的型別。
public record Student ( String id , String name ) {}
將上面代碼中看到的引數化型別(尖括號)從< String >更改為< Student >。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/482585.html
下一篇:從執行緒監視CPU活動更新進度條
