2017-03-15 18 views
0

在其中一個類中,我們正在執行數以千計的deflate格式壓縮,併發線程中的解壓縮。java.util.zip.Deflater&java.util.zip.Inflater類中的線程安全

每個壓縮/解壓縮都是通過分別創建一個Deflater & Inflater的新實例來完成的。

如果這些類是線程安全的,我無法找到任何文檔。任何指針都會有幫助。

+2

你爲什麼在意?我的意思不是好奇嗎?您是否每次都觀察到創建新問題的問題?如果沒有,那麼不要[提前優化](http://stackoverflow.com/q/385506/5221149)。 – Andreas

回答

0

你可能會認爲​​就是爲什麼這些類是線程安全的原因,但我希望你慢慢想它,找到自己的答案:

java.util.zip.Deflater

的deflater類使用RFC 1951中描述的deflate算法壓縮輸入。它具有幾個壓縮級別和三種不同的策略,如下所述。

這個等級是不是線程安全。由於deflate和setInput的分離,這在API中是固有的,

源代碼:http://developer.classpath.org/doc/java/util/zip/Deflater-source.html

結論:由於壓縮是用於減少字符代碼值和字節的原始轉化。在不同的(或不明確的)過程中同時壓縮的字節鏈不是一個好主意。輸出可能導致損壞!

java.util.zip.Inflater

充氣用於解壓縮已根據在RFC 1950的使用是 如下所述的「放氣」標準壓縮的數據。首先你必須設置一些輸入 setInput(),然後膨脹()它。 如果膨脹不會膨脹任何字節,可能有三個原因:

  • 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