2017-05-27 131 views
-1

我有一個包含10000行的CSV文件。我想用N個線程讀取文件,確保只讀一次特定行。例如。如果線程0讀取行號1,則其他線程不應再次讀取該特定行,並且其他線程將處理剩餘的行。任務是每行只能處理一次。只使用多線程讀取一行

我們可以實施這種方法嗎?示例代碼將非常感激。 謝謝!

public class FileReaderThread implements Runnable { 
@Override 
public void run() { 
    BufferedReader br = null; 
    try { 
     br = new BufferedReader(new FileReader("C://Users/mR.cOol/Desktop/Input.csv")); 
     String line = ""; 
     try { 
      while ((line = br.readLine()) != null) { 
       synchronized (line) { 
        System.out.println("In Synchronized block" + " " + Thread.currentThread().getName()); 
        String arr[] = line.split(","); 
        System.out.println(arr[0]); 
       } 
      } 
     } catch (IOException e) { 
     } 
    } catch (Exception e) { 

    } 
} 

}

public class MainClass { 
private static final int workerThread = 2; 

public static void main(String[] args) { 
    Thread thread[] = new Thread[workerThread]; 
    for(int i=0;i<workerThread;i++) { 
     thread[i] = new Thread(new FileReaderThread()); 
     thread[i].start(); 
    } 
} 

}

+2

我們可以在同樣的結果。但是我們通常拒絕這樣做 - 就像你試圖自己解決這個問題所做的努力一樣。你知道,我們不爲你做功課。 – GhostCat

+0

@GhostCat請找到示例代碼。 –

+0

A)永遠不要使用空的catch塊B)你所要求的只是沒有多大意義:讀者只提供讀取方法。所以你的想法是讓多個線程與同一個閱讀器一起工作並不會增加任何價值,相反 - 它使事情變得比需要的複雜得多。相反:首先將所有行讀入列表中,然後讓每個線程處理該列表的不同部分。爲了記錄:你下降了約10%的解決方案,它仍然看起來像你希望我們爲你做的想法。 – GhostCat

回答

0

一個可行的解決方案就是計劃你的線程從文件中讀取數據(字符數)的恆定塊,這意味着每個線程會負責閱讀我的一些字符。

通過這種方式,我們需要將最後一個讀取的字符保存到某個地方,這樣當新的線程到達文件時,它就會確切知道要讀取的字符的位置和數量(startCharacterIndex + chunk-size)。

這種機制可以通過在java中使用volatile變量來完成,它可以保存最後命中字符並在所有線程之間共享。

Volatile值在線程之間共享,並且它們的值永遠不會在線程本地緩存,因此每更新一次它們的值,更新實際引用並且不需要擔心舊的或髒的讀取。

public static volatile int lastReadCharIndex = 0 ; 

另外,還可以實現與AtomicReference對象,在其所有的讀/寫操作都自動完成的和值將始終保持一致