2013-07-09 20 views
16

Performans kritik bir ortamda MessageDigest'i kullanarak birden çok iş parçacığı için birden çok anahtarı kullanmalıyım. MessageDigest'in nesnesinde durumunu depoladığı için iş parçacığı güvenli olmadığını bilmek için geldim. Vida dişlerinin emniyetli şekilde güvenliğini sağlamak için en iyi yol ne olabilir?İş parçacığı için güvenlidir MessageDigest in Java

Kullanım örneği:

MessageDigest messageDigest = MessageDigest.getInstance("SHA-1"); 

//somewhere later, just need to hash a key, nothing else 
messageDigest.update(key); 
byte[] bytes = messageDigest.digest(); 

Özellikle:

  1. Will ThreadLocal çalışması garanti? Performans ceza puanı alacak mı?
  2. GetInstance tarafından döndürülen nesneler farklı mıdır ve birbirleriyle çakışmazlar mı? Dokümantasyon 'yeni' nesnesinde yazıyor, ancak sadece bir paylaşımcının (paylaşımlı) paylaşılan beton sınıfında olup olmadığından emin değilim?
  3. Eğer getInstance() 'gerçek' yeni nesneyi döndürürse, hash değerini hesaplamak için her defasında yeni bir örnek oluşturmamız tavsiye edilir mi? Performans cezası açısından - ne kadar maliyetli nedir?

Kullanım durumum çok basit - sadece basit bir anahtar. Senkronizasyonu kullanamıyorum.

sayesinde

cevap

27

yeni MessageDigest instance'a tek gereken her zaman yaratın.

getInstance()'dan döndürülen tüm örnekler farklıdır. Ayrı ayrı sindirimleri korudukları için olması gerekir (ve bu sizin için yeterli değilse, here's kaynağına bir bağlantı). Yapılandırması pahalı olmayan nesnelerin korunması için, bir threadpool ile birlikte kullanıldığında, bir performans avantajı sağlayabilmektedir MessageDigest özellikle inşa etmek için pahalı değildir (tekrar, kaynağa bakın).

+1

I) (İş Ahlakına Dair getInstance görüyorsanız, bunun yeni bir nesne oluşturmak için görünmüyor, daha çok nesne almak için Güvenlik çağırır Nesne [] OBJS = Security.getImpl aşağıda test vakası yazdı : \t MessageDigest messageDigest1 = MessageDigest.getInstance ("SHA-1"); \t MessageDigest messageDigest2 = MessageDigest.getInstance ("SHA-1"); // güncelleştirin ve özetleyin ve her iki messageDigest nesnesinin de farklı olduğunu ve bunların iç nesnelerinin/arabelleklerinin de farklı olduğunu gördü. Yani, ben ThreadLocal çalışmalı. Ve evet, iş parçacığı havuzu olan bir web sunucusudur. ThreadLocal'ı kullanacağım. Teşekkürler, –

+3

@AnilPadia - I ** şiddetle **, ** ThreadLocal kullanılarak ** kullanılmaması önerilir. Bu erken bir optimizasyon. Yeni bir 'MessageDigest' oluşturmak için yaklaşık 2 * micro * -saniye süren bir mikro ölçüt yazdım. Bu, sindirimi kullanan kod tarafından * uzak * olacaktır. – parsifal

+0

ThreadLocal'ı kullanırken gördüğünüz sorunlar nelerdir? Yüzlerce iş parçam olsa bile, yüzlerce nesne olacak. Bu nesnelerin bellek ayak izlerini gerçekten daha az buldum. ThreadLocal benim için iyi çalışıyor. Ayrıca nesneler oluşturmayı test ettim ve 4 mikrosaniye sürdü. Gerçekten neden ThreadLocal –

3

Alternatif olarak, MessageDigest için Apache Commons'ın iş parçacığı güvenli sarıcı olan DigestUtils kullanın.

sha1() neye ihtiyacınız yapar:

byte[] bytes = sha1(key)

+0

Aşağıdaki cevaba bakın; DigestUtils.getDigest() yalnızca MessageDigest.getInstance() işlevini çağırır ve işaretli bir özel durumu işaretlenmemiş bir özel duruma dönüştürürken, DigestUtils MessageDigest'den daha fazla iş parçacığı değildir. – Siddhu

+1

Buradaki nokta, MessageDigest'in iş parçacığı güvenli olmamasıdır, bu nedenle aynı örneği aynı anda yeniden kullanmak, öngörülemeyen sonuçlara neden olur. Yeni/farklı bir örnek kullanarak (örneğin MessageDigest.getInstance çağrılarak) her zaman sorununuzu çözer. DisgestUtils, kolaylık yöntemlerinin her birinin yeni bir MessageDigest örneği kullandığı, yani her birinin (birkaç aramadan sonra) MessageDigest.getInstance yeni bir örnek oluşturduğu anlamına gelen thread-safe'dir. örneğin DigestUtils'e yapılan her çağrı. sha256Hex ("Dizgim"); MessageDigest – Legna

1

DigestUtils olmak görünmüyor artık ham MessageDigest daha threadsafe. Kapaklar altında hala MessageDigest.getInstance kullanır.

+1

'un farklı bir örneğini kullanır. Buradaki nokta, MessageDigest'in iş parçacığı güvenli olmamasıdır, bu nedenle aynı örneği eşzamanlı bir ortamda yeniden kullanmak, öngörülemeyen sonuçlara neden olur. yeni/farklı bir örnek kullanarak (örneğin MessageDigest.getInstance'ı arayarak) sorununuzu çözer. DisgestUtils, kolaylık yöntemlerinin her birinin yeni bir MessageDigest örneği kullandığı, her birinin (birkaç aramadan sonra) MessageDigest.getInstance'ın yeni bir örnek oluşturduğu anlamındadır. , örneğin DigestUtils'e yapılan her çağrı. sha256Hex ("Dizgim"); MessageDigest – Legna

+0

farklı bir örneğini kullanır. Açıklama için teşekkürler. –

İlgili konular