2009-03-27 7 views
1

J'ai une servlet qui sert de proxy pour extraire les images en lisant les images comme des octets d'un flux d'entrée HttpURLConnection, puis en écrivant les octets dans le flux de sortie de la réponse. Voici l'extrait de code pertinent:Meilleure pratique de mise en cache des images lues à partir d'un flux d'entrée Java

HttpURLConnection connection = (HttpURLConnection)url.openConnection(); 
connection.setConnectTimeout(CONNECT_TIMEOUT); 
connection.setReadTimeout(READ_TIMEOUT); 

InputStream in = connection.getInputStream(); 
OutputStream out = resp.getOutputStream(); 

byte[] buf = new byte[1024]; 
int count = 0; 
while ((count = in.read(buf)) >= 0) { 
    out.write(buf, 0, count); 
} 

Je voudrais commencer à mettre en cache l'image dans le servlet proxy. J'envisage d'envelopper le tableau d'octets et de le stocker dans une carte, mais je soupçonne qu'il existe un meilleur moyen. J'ai remarqué le paquet javax.imagio mais je n'ai aucune expérience avec et je ne sais pas si c'est pertinent ici. Plus précisément, je cherche des idées sur la façon de stocker l'image et pas tellement la mécanique de la mise en cache.

Répondre

2

Si vous ne mettez en cache que les images, je vous recommande de conserver l'image en tant que tableau d'octets, pas en tant qu'image. Utiliser imageio pour lire l'image décompresserait les images et prendrait beaucoup plus d'espace mémoire.

La classe WeekHashMap est probablement le moyen le plus simple de mettre en cache des éléments, mais vous avez peu de contrôle sur la façon dont les entrées sont expulsées.

+0

Utilisation parfaite pour WeakHashMap. –

+2

Ce n'est pas un bon usage de 'WeakHashMap'. S'il vous plaît voir http://www.codeinstructions.com/2008/09/weakhashmap-is-not-cache-understanding.html pour une explication de pourquoi pas. Astuce: Vos valeurs disparaîtront dès que personne ne tiendra une référence à vos clés. – uckelman

2

Dans certains cas limités, une carte de hachage pourrait fonctionner. Mais vous devez penser à:

(1) Comment vous allez purger les images en cache de la mémoire lorsque le cache est "plein" (mais vous définissez cela - probablement une quantité maximale de mémoire que vous souhaitez consacrer à la mise en cache). (2) Comment allez-vous faire face à la concurrence? (3) De même, comment allez-vous gérer le cas où le client A demande une image, puis le client B demande la même image alors qu'il est encore chargé dans le cache du client A.

solution simple à (1) pourrait être de toujours stocker SoftReferences aux données d'image et laissez la JVM prendre soin de décider quand les purger (en gardant à l'esprit qu'il pourrait les purger arbitrairement au-delà de votre contrôle). Sinon, vous devez développer une sorte de politique (d'abord, image la plus longue, image la plus petite/la plus grande etc., image qui prendra le plus de temps pour être rechargée, etc.) - vous seul connaissez vos données et votre utilisation , donc vous devez trouver la bonne politique.

Pour (2), ConcurrentHashMap vous aidera généralement; vous pouvez décider d'utiliser des verrous explicites et d'autres utilitaires de concurrence dans les cas particuliers. Pour (3), une solution assez élégante proposée par Goetz et al est de détourner la classe Future. Dans votre carte, vous stockez un avenir à l'objet mis en cache (ou à votre objet "entrée de cache"). Si un demandeur trouve qu'un Futur a déjà été ajouté à la carte, il peut alors appeler get() et attendre que l'autre thread termine la mise en cache des données. (Vous pouvez obtenir un effet similaire avec un verrouillage et une condition explicites, mais Future prend une partie du travail pour vous.)

P.S. Je suis d'accord avec l'affiche qui dit que vous voulez probablement stocker les images dans leur forme codée originale. Mais à partir de votre code, je suppose que c'était probablement ce que vous aviez l'intention de faire.

Questions connexes