12

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();
    }
}

すべてのスレッドがコンテンツを共通ファイルに書き込むようにするにはどうすればよいですか?

4

5 に答える 5

22

FileWriter追加モードを使用するコンストラクターを使用する

FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);
于 2013-10-06T10:36:02.653 に答える
9

ブロッキング キューからの読み取りとファイルへの書き込みを継続する単一のファイル ライター スレッドを用意します。他の 20 個のスレッドはすべて、データをブロッキング キューに入れるだけです。これにより、20 個の書き込みスレッド間の競合が防止されます。

于 2014-03-04T08:24:10.473 に答える
4

あなたのコードに関連するいくつかのポイント:

1.の作成方法がFileWriter正しくありません。ファイルにデータを追加する場合は、追加のboolean引数 ( Make it true)を含むコンストラクターを使用します。

public FileWriter(File file,boolean append) throws IOException

例えば ​​:

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

2.共通ファイルを共有する複数のスレッドについて話していますが、コード内に同期ブロックが見当たりません。同期を使用して、一度に 1 つのスレッドのみが共有リソースにアクセスできるようにします。

于 2013-10-06T11:22:11.977 に答える
2

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

追加モードを示すを使用する必要があります。

于 2013-10-06T10:38:44.417 に答える
-4

私は初心者です。だから私は間違っているかもしれません!ただし、コードが機能する場合と機能しない場合があります。それはランナブルまたはスレッドの実行ですか? これに注意してください:

MyClass implements Runnable {

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

}

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

私たちの多くはそのようにしています(私はやった、やります:)、そしてそうです!各スレッドは異なる obj でロックを取得し、OS が何らかのメカニズムを使用して同じファイルへの書き込みを同期しない限り、予期しない結果になる可能性があります (わかりません)。もしそうなら、あなたの同期化されたものは役に立たない(私の例ではとにかく役に立たない).アイデア...少なくとも私にとっては複雑なもの

私の意見では、 SHARESMUTABLESTATEのクラスのインスタンスが1 つある場合、synchronized は便利です。(今のところ、同期と静的については忘れましょう)

MyClass には状態がありますか? いいえ、共有されますか? いいえ、私の例ではありません。それはうまくいきますか?このようではありません。多分こんな感じ?

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

PS: すべてのスレッドで start を呼び出すのを忘れていました。

于 2014-01-24T18:20:16.403 に答える