簡體   English   中英

帶線程池的Java線程隊列

[英]Java threading queue with thread pool

我已經編寫了一個程序,該程序使用單線程將文件中的數據讀取到鏈接列表中,並將其稱為LL1。 由此,我創建了一個線程池,該線程池為每個線程分配一個處理任務,該任務從LL1讀取數據並將其計算結果輸出到新的鏈表。 由此,我需要將每個線程的新鏈表輸出到單個文件中。 我試圖在順序塊中輸出每個鏈接列表,以便線程不混合數據,因此我使用了如下同步點:

public synchronized void appendContents(List<Vector2> output1) {
    try {
        sFileName = outFilePath + "\\file" +fileCount+ ".cntr";
        File oFile = new File(sFileName);
        if (!oFile.exists()) {
            oFile.createNewFile();
        }
        if (oFile.canWrite()) {
            //BufferedWriter oWriter = new BufferedWriter(new FileWriter(sFileName, true));
             FileWriter wstream = new FileWriter(oFile, true);
             BufferedWriter outWriter = new BufferedWriter(wstream);
             for(int i = 0; i < output1.size(); i++)
             {
                //replace the space marker values with a newline
                if(output1.get(i).y == -200.0){
                outWriter.newLine();
                }else{
                outWriter.write(String.valueOf(output1.get(i).x) + " " + String.valueOf(output1.get(i).y) + " " + String.valueOf(interval));
                outWriter.newLine();    
                }
             }           
             outWriter.close();
        }
    }
    catch (IOException oException) {
        throw new IllegalArgumentException("Error appending/File cannot be written: \n" + sFileName);
    }

我面臨的問題是數據沒有按順序輸出,這就是我所需要的,即

list1 value                              list1 value
list1 value         _______________\     list2 value
list1 value         ________________\    list1 value 
list2 value         RATHER THAN ____/    list3 value
list2 value         ---------------/     list2 value
list2 value                              list1 value
list3 value                              list2 value
list3 value                              list1 value
list3 value                              list3 value
list3 value                              list3 value

如果有人能朝正確的方向邁出一步,將不勝感激。 謝謝,

插口

synchronized的目的是在共享資源上進行同步,以便一次只有一個Thread可以訪問關鍵部分。 我假設您正在生成三個Thread實例,每個實例在其自己的對象上調用appendContents

synchronized方法在this上隱式同步,但是由於所有三個Thread都在不同的對象(即)上同步。 this不同的是,沒有任何一個阻止它們。

據我了解,您每次為每個列表元素運行新任務嗎?

那么您只需編寫Callable task->將結果保存在Feature.Put中將特征與結果(resultFeatureFromList)相對應。 最后做些類似的事情:我使用Guava Lib的Function;

Iterables.transform(resultList<Feature>,new Function(){
   public resultComputition apply(Feature resultFeatureFromList){
               return resultFeatureFromList.get();
   }
});

因此,總而言之,您將以正確的順序運行所有任務。 在拉完所有東西之后,只需等待結果即可。

根據user2870704的答案 ,您可以按以下方式構建應用程序:

  • 讓線程讀取文件內容;
  • 對於文件中的每個項目,向您的線程池提交一個Callable任務;
  • 將返回的Future存儲在一個列表或列表列表中-您定義所需的粒度;
  • 在同一線程中打開輸出文件,並遍歷結果列表以進行寫入。

舉個例子:

void readAndOutput(String inputFilePath, String outputFilePath) {
    List<List<Future<Result>>> results = readAndSpawnTask(inputFilePath);

    PrintWriter out = new PrintWriter(new File(outputFilePath));

    for (List<Future<Result>> block : results) {
        for (Future<Result> r : block) {
            out.println(r.get().toString());
        }
    }

    out.flush();
    out.close();
}


List<List<Future<Result>>> readAndSpawnTask(String path) {
    List<List<Future<Result>>> results = new ArrayList<>(numOfBlocks);
    BufferedReader in = new BufferedReader(new FileReader(new File(path)));

    for (int i = 0; i < numOfBlocks; ++i) {
        results.add(new LinkedList<Future<Result>>());
    }

    for (String line = in.readLine(); line != null; line = in.readLine()) {
        int respectiveBlock;
        Callable<Result> task;
        // Process line and convert it into a task of your own.
        // Determine in which block the result goes into.
        Future<Result> r = threadPool.submit(task);
        results.get(respectiveBlock).add(r);
    }

    in.close();

    return results;
}

如果您需要和/或需要並發,則其想法是在單個線程中訪問文件。 使用Future列表,可以保證以正確的順序寫入結果,並且主線程將阻塞,直到所需的結果准備就緒為止。

當然,您仍然必須考慮以上代碼中引發的可能異常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM