8

Java プログラムが System.out.println() を呼び出すか、Scala プログラムが println() を呼び出すと、スレッドはブロックされますか?

大量のサブタスクを含む Scala プログラムを作成しています。各サブタスクは Future 内で実行されます。アクターとフューチャー内のコードをブロックしないことをお勧めします。これにより、後続のタスクも待機する必要がなくなります。しかし、私はコンソールに非常に印刷したいです。

ブロック操作の場合: パフォーマンスを最適化するにはどうすればよいですか?

  • コンソール出力に専用スレッドを使用して、そのスレッドだけがブロックされるようにする必要がありますか?
  • 他にアドバイスはありますか?

もちろん、出力の量を減らすか、StringBuilder で出力を収集してバッチでまとめて出力することで、出力操作の数を減らすことができます。

4

2 に答える 2

14

Java プログラムが System.out.println() を呼び出すか、Scala プログラムが println() を呼び出すと、スレッドはブロックされますか?

はいといいえ。 System.outPrintStream同期クラスです。したがって、大量の書き込みを行う複数のスレッドSystem.outは、確実にお互いをブロックします。ただし、スレッドがロックを取得すると、IO がスレッドをブロックするかどうかはアーキテクチャに依存します。基盤となるハードウェアの容量を超える大量の IO を書き込むと、書き込みブロックされます。また、(バッファリングではなく) 小さな書き込みをたくさん行うと、スレッドも遅くなります。

コンソール出力に専用スレッドを使用して、そのスレッドだけがブロックされるようにする必要がありますか?

素晴らしいアイデアです、はい。次に、このスレッドは、単一BufferedWriterまたは何らかの種類の log4j または他のロギング パッケージを介して書き込むことができ、 System.out. 同期するメッセージをキューに入れるには a のようなものを使用する必要がありBlockingQueueますが、IO チャネルが永続化できるよりも速くメッセージを生成しない限り、IO はこのキューをブロックしません。

もちろん、出力の量を減らすか、StringBuilder で出力を収集してバッチでまとめて出力することで、出力操作の数を減らすことができます。

がこれBufferedWriterを処理します。

他にアドバイスはありますか?

  • 前述のように、より優れたロギング パッケージまたはシングル スレッド ライターを使用してください。
  • より多くの IO 帯域幅を持つ別の物理ディスクにログを書き込みます。
  • メモリ ファイル システムまたはハードウェアに切り替えて、IO 帯域幅を増やします。SSD++。
  • ネットワーク経由で別のボックスに送信して、実際の永続的なオフ ボックスを実行します。
  • aGzipOutputStreamを使用してその場で圧縮します。
于 2013-06-25T17:46:45.217 に答える
5

場合によりますWindows OS では、これはブロック操作であり、コンソールに何かを出力するために多くのカーネル関連の作業が必要です。UNIXライクな OSでは、操作がバッファリングされるため、遅いとは認識されません。

バッファアプローチを使用することをお勧めします。別のスレッドを用意することもお勧めです。または、出力がそれほど重要でない場合は、ファイルに書き込むことができます。これは、コンソールに書き込むよりもはるかに高速です。

于 2013-06-25T17:45:32.717 に答える