2012-10-12 2 views
1

J'ai une classe pour le chargement d'objets de persistance avec la méthode suivante à PersistenceController classe:Synchronisez un chargeur de persistance en Java

Item loadItem(int id); 

Alors maintenant, je veux mettre en œuvre la méthode suivante dans un autre contrôleur:

synchronized Item getItem(int id){ 
    Item result= getItemFromMemory(id); 
    if (result==null){ 
     result=PersistenceController.loadItem(id); 
    } 
    return result; 
} 

L'objectif est de garantir qu'une seule instance (ou zéro) d'un élément avec le même identifiant en mémoire en même temps. Cette méthode fonctionne mais a un problème: Chaque élément de chargement doit attendre l'un l'autre. Je voudrais changer le schéma de synchronisation pour qu'un appel n'attende les autres que si les deux ont le même identifiant.

Quel est le meilleur moyen de le faire?

+0

vous devez alors verrouiller l'ID. voir cette réponse [1]: http://stackoverflow.com/questions/659915/synchronizing-on-an-integer-value – MLN

+0

Vos identifiants sont-ils réellement représentés en tant que primitives int? Si vous utilisez un objet pour votre classe d'identification, vous pouvez synchroniser sur l'objet ID lui-même au lieu de synchroniser la méthode getItem. – Luhar

+0

Je ne savais pas que vous pouvez prendre un mutex à partir d'un entier. J'ai une question à ce sujet? Que se passe-t-il si, dans une autre partie du programme, la même technique est utilisée (pour une autre tâche sans rapport) et que les identifiants se rencontrent? Cela pourrait se terminer par une attente incorrecte? Je envisage d'utiliser un SparseArray pour la manipulation des serrures est correcte? – Addev

Répondre

1

Je suppose que seule façon d'obtenir ce que vous voulez est d'écrire un Custom Lock en utilisant AbstractQueuedSynchronizer qui va créer de verrouillage basé sur entier vous passez, mais il est fortement déconseillé

Synchronizing on an Integer value propose une solution à l'aide ConcurrentHashMap mais il a ses propres défauts . Vous ne pouvez pas supprimer la valeur de la carte lorsque vous avez acquis le même verrou, il n'y a donc aucun moyen de supprimer la valeur sauf si vous écrivez Synchronized instance de ConcurrentHashMap que vous ne voulez pas.

Une approche plutôt réalisable serait d'augmenter le nombre de verrous.

Questions connexes