2013-10-06 87 views
4

我想通過Java中的多個線程將一些內容寫入文件。每個線程讀取不同的輸入文件,進行一些計算並將一些(不同的)內容寫入公共輸出文件。問題在於最終輸出文件只包含最後一個終止線程寫入的內容,而不包含其他線程寫入的內容。線程的相關代碼 -Java - 寫入同一文件的多個線程

public void run() 
{ 
    try 
    { 
     File file = new File("/home/output.txt"); 
     if (!file.exists()) 
     { 
      file.createNewFile(); 
     } 
     FileWriter fw = new FileWriter(file.getAbsoluteFile()); 
     BufferedWriter bw = new BufferedWriter(fw); 

     BufferedReader br = new BufferedReader(new FileReader(inputfile)); // each thread reads a different input file 
     String line=""; 

     while((line=br.readLine())!=null) 
     { 
      String id = line.trim();    // fetch id 

      StringBuffer sb = processId(userId); // process id 

      synchronized(this){ 
      bw.write(sb.toString() + "\n");  // write to file 
      } 
     } 
     bw.close(); 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
} 

如何讓所有線程將其內容寫入公共文件?

+0

你必須追加到現有的文件(''FileOutputStream''有一個布爾標誌)。但是你也必須寫''synchronized'',以確保只有一個線程同時寫入。 – qqilihq

+0

如果您可以使用StringBuilder,請勿使用StringBuffer。在這種情況下processId()可以返回一個String。 –

+2

您需要在所有線程中打開該文件並協調其寫作。否則,你很可能會陷入混亂。我建議你有一個單線程執行程序並提交任務給它寫入文件。這將確保單線程寫入。 –

回答

11

使用了一個附加模式

FileWriter fw = new FileWriter(file.getAbsoluteFile(), true); 
+0

如果追加爲true,則字節將被寫入文件的末尾而不是開頭。因此,除此之外,它也應該起作用(應該在開始時寫入字節)。我在OP中看不到任何問題。 –

1

FileWriter fw = new FileWriter(file.getAbsoluteFile(),true);

應該使用哪些指示追加模式FileWriter構造。

2

關係到你的代碼幾點:

1.要創建的FileWriter是不正確的方式。如果你想將數據追加到文件,使用包含一個額外boolean參數的構造(使它true):

public FileWriter(File file,boolean append) throws IOException 

例如:

FileWriter fw = new FileWriter(file.getAbsoluteFile(),true); 

2.你是在談論多個線程將共享一個共同的文件,但我看不到代碼中的任何同步塊。使用同步來確保一次只有一個線程可以訪問共享資源。

+0

謝謝,請參閱我的編輯。 –

+0

嗨,我想你應該對BufferedWriter進行鎖定,而不是這個。 假設有兩個線程命名爲Thread-A,而Thread-B嘗試寫入該文件。現在,在這個例子中,兩者都會嘗試鎖定,但是它們應該鎖定上面程序中的「bw」共享資源。 你對此有何看法? –

-2

我是新手。 所以我可能會犯錯!但是你的代碼可能會或可能無法工作。這是運行一個Runnable或線程?請注意:

MyClass implements Runnable { 

public void run() { 
....synchronized(this).. 
} 

} 

Thread t1 = new Thread(new MyClass()); 
Thread t2 = new Thread(new MyClass()); 

我們中的許多人都這樣做(我做到了,做到了:),並且是!每個線程都會在不同的obj上獲得一個鎖,除非操作系統使用某種機制將寫入同步到同一個文件(我不知道),否則可能會導致意外的結果。如果是這樣,那麼你的synchonized是無用的(無論如何在我的例子中),如果它不是你很漂亮....也作爲一個註釋,可能有另一個使用這個output.txt的過程,我們沒有想法...至少對我來說

我的看法複雜的東西,就是如果你有股份類的一個例如,MUTABLESTATE同步是非常有用的。 (讓我們忘了現在同步和靜態)

MyClass是否有狀態?不是,它是共享的嗎?不,在我的例子中。它會起作用嗎?不是這樣的。可能是這樣嗎? PS:我忘了在每個線程中調用開始。

2

有一個單獨的文件寫入程序線程,它不斷讀取阻塞隊列並寫入文件。所有其他的20個線程只會將數據放入阻塞隊列中。這將防止20個寫入程序線程之間的爭用。

相關問題