Java プログラムが System.out.println() を呼び出すか、Scala プログラムが println() を呼び出すと、スレッドはブロックされますか?
はいといいえ。 System.out
はPrintStream
同期クラスです。したがって、大量の書き込みを行う複数のスレッドSystem.out
は、確実にお互いをブロックします。ただし、スレッドがロックを取得すると、IO がスレッドをブロックするかどうかはアーキテクチャに依存します。基盤となるハードウェアの容量を超える大量の IO を書き込むと、書き込みがブロックされます。また、(バッファリングではなく) 小さな書き込みをたくさん行うと、スレッドも遅くなります。
コンソール出力に専用スレッドを使用して、そのスレッドだけがブロックされるようにする必要がありますか?
素晴らしいアイデアです、はい。次に、このスレッドは、単一BufferedWriter
または何らかの種類の log4j または他のロギング パッケージを介して書き込むことができ、 System.out
. 同期するメッセージをキューに入れるには a のようなものを使用する必要がありBlockingQueue
ますが、IO チャネルが永続化できるよりも速くメッセージを生成しない限り、IO はこのキューをブロックしません。
もちろん、出力の量を減らすか、StringBuilder で出力を収集してバッチでまとめて出力することで、出力操作の数を減らすことができます。
がこれBufferedWriter
を処理します。
他にアドバイスはありますか?
- 前述のように、より優れたロギング パッケージまたはシングル スレッド ライターを使用してください。
- より多くの IO 帯域幅を持つ別の物理ディスクにログを書き込みます。
- メモリ ファイル システムまたはハードウェアに切り替えて、IO 帯域幅を増やします。SSD++。
- ネットワーク経由で別のボックスに送信して、実際の永続的なオフ ボックスを実行します。
- a
GzipOutputStream
を使用してその場で圧縮します。