2017-03-15 12 views
0

クラスのうちの1つでは、並行スレッドで何千ものデフレート形式の圧縮と解凍を実行しています。java.util.zip.Deflaterクラスとjava.util.zip.Inflaterクラスはスレッドセーフです

すべての圧縮/解凍は、Deflater & Inflaterの新しいインスタンスをそれぞれ作成することによって行われます。

これらのクラスがスレッドセーフである場合は、ドキュメントを見つけることができません。任意のポインタが役立つだろう。

+2

なぜ気になりますか?好奇心以外の意味ですか?あなたは毎回新しいものを作成することに問題を観察しましたか?もしそうでなければ、[時期尚早最適化]をしないでください(http://stackoverflow.com/q/385506/5221149)。 – Andreas

答えて

0

あなたは​​は、これらのクラスは、スレッドセーフである理由ですが、私はあなたがゆっくりとそれについて考え、自分で答えを見つけたいと思うことがあります。

java.util.zip.Deflater

デフレータクラスは、の入力をRFC 1951に記述されているデフレートアルゴリズムで圧縮します。これには、いくつかの圧縮レベルと、以下で説明する3つの異なる戦略があります。

このクラスはではなく、スレッドセーフです。これはdeflateとsetInputの分割のためAPIに固有のものです。

ソースコード:http://developer.classpath.org/doc/java/util/zip/Deflater-source.html

結論:圧縮が少なく文字コード値とバイトの生変換であるからです。 異なる(またはあいまいな)プロセスで同時に圧縮されているバイトのチェーンを編集することはお勧めしません。出力が破損する可能性があります。

java.util.zip.Inflater

のInflaterは解凍するRFC使用量は以下のよう である1950年に記載された「収縮」規格に従って圧縮されたデータが使用されます。まず、入力を setInput()に設定してからinflate()しなければなりません。 inflateがバイトを膨らませない場合は、次の3つの理由が考えられます。

  • needsInput()は、入力バッファが空であるためtrueを返します。setInput()を入力する必要があります。
    注:ストリームが終了すると、needsInput()もtrueを返します。
  • needsDictionary()はtrueを返します。setDictionary()というプリセット辞書を用意する必要があります。
  • finished()はtrueを返し、インフレータは終了しました。
最初の出力バイトが生成されると、後の段階では辞書は必要ありません。

ソースコード:http://developer.classpath.org/doc/java/util/zip/Inflater-source.html

結論:データの大きな塊がを解凍しているという事実は、我々はいくつかの入力(誇らしげチャンク)を取ることができることを意味し、その後にいくつかのアルゴリズムを適用元のデータを出力します。この場合、スレッドセーフは義務付けられていません。このクラスの初期データ(拡張されていないバイト)は、実行する追加の計算(バイトの削除、文字の追加、変更)とは無関係に、独立したままにできるためです。結局のところ、大量のデータはそのまま圧縮解除される用意ができています。

1

ソースコードを見ると、コードは​​であり、スレッドセーフであることがわかります。

複数のスレッドがでそれを使用しようとする場合、それがボトルネックになり、つまりしかし、​​が、それはスレッドセーフですがようDeflater/Inflator単一のインスタンスしか、一度に一つの操作を行うことができることを意味し、それは、マルチスレッドではありません同じ時間。

スレッドセーフですが、スレッド間でインスタンスを共有すべきではありません。これは、複数のスレッドを実行することによるパフォーマンス上の利点が減るためです。

+0

はい私はコードを調べましたが、同期から離れているようですが、byte [] buf、ZStreamRef zsRefなどのクラスで状態が共有されているようです。同じインフレータ/デフレーターインスタンスが複数のスレッドによって同時に使用されている場合、この共有状態のために問題が発生しないかどうかはわかりません。 – tarunkumar

関連する問題