2

ループ内で (入力ストリームを介して) ソケットから読み取り、(BufferedWriter を介して) ファイルに書き込むクライアント コードがあります。

dataInStream = new BufferedInputStream(dataSocket.getInputStream());
outputFile = new BufferedWriter(new FileWriter(filename));
byte bytes[] = new byte[64];
Message msg = new Message();
int bytesRead = 0;
while (true) {                
   bytesRead = dataInStream.read(bytes, 0, 64);
   // create a message from the raw data...
   msg.parse(bytes);
   // write it to the file as a String
   outputFile.write(msg.toString());
   outputFile.flush();
}

(一般的なフローを示す単純化されたコード - 追加のライター スレッドを追加する必要がある場合にのみ学習に関心があります)

リーダー スレッドとライター スレッドの間にConcurrentLinkedQueueのようなものを使用して、ファイル書き込み操作を別のスレッド (つまり、「ライター」) に分割する必要があるのはどの時点 (データ レートに関して) でしょうか?

要件のメッセージ レートが低い (つまり、最大で 1400 バイトのメッセージが 1 秒あたり ~10)

スループットをベンチマークするために実行したテスト コードは、150000 バイト/秒を簡単に処理できることを示しました。データ レート (結果が何であれ) は一定であるため、ライターは、リーダーでデータ損失を引き起こすのに十分な時間ブロックすることはありますか?

それとも、常にリーダースレッドライター スレッドを用意するのが良い方法ですか?

4

1 に答える 1

0

どの時点 (データ レートに関して) で、ファイル書き込み操作を別のスレッド (つまり、「ライター」) に分割する必要があるか

コードの最適化を開始する (より複雑にする) のは、パフォーマンスの問題が発生している場合、またはプロファイラーが良いアイデアであると判断した場合のみにしてください

それとも、常にリーダー スレッドとライター スレッドを用意するのが良い方法ですか?

他の情報がなくても良い方法です。ただし、あなたの場合、データ要件を知っているので、大量のスループットが予想される場合、またはディスク側で IO バウンドが予想される場合にのみ実行する必要があります。

要件のメッセージ レートが低い (つまり、最大で 1400 バイトのメッセージが 1 秒あたり ~10)

これは、余分なコードの複雑さを保証するほど多くのデータ スループットではありません。

ライターは、リーダーでデータ損失を引き起こすのに十分な時間ブロックできますか?

ほとんどの場合、ローカル ディスク IO はネットワークよりも高速になります。このような状況に陥る可能性はありますが、あまり一般的ではないと思います。カーネルはソケット上で大量のバッファリングを提供しており、カーネル バッファがオーバーフローした場合、TCP/IP プロトコルは再送信するため、長時間ブロックしてもデータは失われません

于 2012-06-01T18:56:21.410 に答える