ChaqueReferenceEntryLes entrées du tableau sont toutes uneReferenceEntryChaîne.
UnReferenceEntryContientkey、hash、value Reference、nextChamp,Sauf dansReferenceEntryChaîne constituée dans un élément de tableau.
ReferenceEntryPeut être fortement référencékey,C'est possible.WeakReferenceTypekey,Pour réduire l'utilisation de la mémoire,Peut également être configuré en fonction deexpireAfterWrite、expireAfterAccess、maximumSizePour décider siwriteChaîne etaccessLa chaîne détermine les détails à créerReference:StrongEntry、StrongWriteEntry、StrongAccessEntry、StrongWriteAccessEntryAttendez..
map Le noeud central peut être dans l'état suivant :
Efficace:
Live: Une clé valide est définie /Valeur
Loading:Chargement
Invalide:
Expired:Le temps est écoulé.(Clé/ Les valeurs peuvent encore être définies )
Collected:Clé/ Valeur partiellement collectée , Mais pas encore nettoyé
Unset: Marqué comme non défini , En attente de nettoyage ou de réutilisation
ValueRéférences
Pourquoi?ReferenceLes ordres,Parce queCachePour soutenir:
WeakReference K
SoftReference、WeakReference V
ValueReference Parce queCache Prise en charge des Value、SoftReference ValueEtWeakReference Value, Il correspond donc à trois classes d'implémentation :StrongValueReference、SoftValueReference、WeakValueReference.
Pour soutenir le mécanisme de chargement dynamique ,Il en a un autre.LoadingValueReference, Un chargement dynamique est nécessaire keyLorsque la valeur de:
Emballez d'abord cette valeur dans LoadingValueReference, Pour exprimer key La valeur correspondante est déjà chargée
Si d'autres Threads doivent également interroger keyLa valeur correspondante, Pour obtenir cette citation , Et attendre que la valeur soit chargée ,Par Assurez - vous que la valeur n'est chargée qu'une seule fois
Une fois la valeur chargée ,Oui.LoadingValueReference Remplacer par un autre ValueReferenceType
ValueReference La paire est conservée dans l'objet ReferenceEntryRéférences,C'est parce queValueParce queWeakReference、SoftReferenceLorsqu'il est recyclé, Besoin de l'utiliser key Retirer l'élément correspondant de SegmentDetableSupprimer dans.
Dans unSegmentMoyenne,Tous lesReferenceEntry Composition :
accessChaîne(accessQueue)
writeChaîne(writeQueue)
Pour réaliserLRU,Guava CacheInSegment Ces deux chaînes ajoutées dans , Ce sont des listes bidirectionnelles ,AdoptionReferenceEntry Le lien suivant dans :
previousInWriteQueue
nextInWriteQueue
previousInAccessQueue
nextInAccessQueue
WriteQueueEtAccessQueue Tout est personnalisé offer、peek、remove、pollAttendre l'opération:
offerFonctionnement,Si:
Directement à la fin de la chaîne
La queue de la chaîne qui relie ce noeud
removeFonctionnement:
Retirer le noeud directement de la chaîne
pollFonctionnement:
Supprimer le noeud suivant du noeud de tête ,Et revenir à.
SegmentDeevictPolitique de nettoyage
Déclenche le nettoyage au début et à la fin de chaque opération d'appel , Ceci est comparé au nettoyage normal du moniteur de fil de cache Save , Réduit les frais généraux .
Mais si la méthode n'est pas appelée depuis longtemps , Cela peut entraîner un nettoyage intempestif pour libérer de l'espace mémoire .
evict Il s'occupe principalement de quatre Queue:
keyReferenceQueue
valueReferenceQueue
writeQueue
accessQueue
Les deux premiersqueueParce queWeakReference、SoftReference Ajouté lors de la collecte des ordures , Il suffit de traverser tout le queue, Faire correspondre les entrées de LocalCacheSupprimer:
keyReferenceQueueStockageReferenceEntry
valueReferenceQueueCe qui est stockéValueReference
À partir deCache Supprimer dans nécessite key,Et doncValueReferenceIl faut avoir raison.ReferenceEntryRéférences.
Les deux derniersQueue, Il suffit de vérifier si les expireTemps, Et chercher à partir de zéro ce qui est déjà expireDeEntry, Enlevez - les .
SegmentDansputFonctionnement:put Fonctionnement relativement simple , Il faut d'abord qu'il obtienne la serrure , Et essayer de nettoyer , La logique qui suit est similaire ConcurrentHashMapDansrehash, Localiser et injecter des données . Ce qu'il faut expliquer, c'est quand on trouve un EntryHeure, Il faut d'abord juger ValueRefernece La valeur dans a été effectivement recyclée , Parce qu'ils peuvent être WeakReference、SoftReferenceType, Si elle a été recyclée , Alors écrivez la nouvelle valeur à . Et enregistre les événements de suppression causés par l'opération courante à chaque mise à jour , Préciser la raison correspondante :COLLECTED、REPLACEDAttendez., Ces événements enregistrés sont appelés uniformément à la sortie CacheEnregistréRemovalListener, Comme la gestion des événements peut prendre beaucoup de temps , Donc ici, la logique de gestion d'événements n'est faite qu'après la sortie de la serrure .Enfin, Mise à jour des Entry Après ça, j'ai essayé de mettre ceux qui expireDeEntrySupprimer.En plusput Une mise à jour est également nécessaire pendant l'opération writeQueueEtaccessQueue L'exactitude sémantique de .
SegmentAvecCacheLoaderDegetFonctionnement
V get(K key, int hash, CacheLoader<? super K, V> loader) throws ExecutionException {
checkNotNull(key);
checkNotNull(loader);
try {
if (count != 0) { // read-volatile
// don’t call getLiveEntry, which would ignore loading values
ReferenceEntry<K, V> e = getEntry(key, hash);
if (e != null) {
long now = map.ticker.read();
V value = getLiveValue(e, now);
if (value != null) {
recordRead(e, now);
statsCounter.recordHits(1);
return scheduleRefresh(e, key, hash, value, now, loader);
}
ValueReference<K, V> valueReference = e.getValueReference();
if (valueReference.isLoading()) {
return waitForLoadingValue(e, key, valueReference);
}
}
}
// at this point e is either null or expired;
return lockedGetOrLoad(key, hash, loader);
} catch (ExecutionException ee) {
Throwable cause = ee.getCause();
if (cause instanceof Error) {
throw new ExecutionError((Error) cause);
} else if (cause instanceof RuntimeException) {
throw new UncheckedExecutionException(cause);
}
throw ee;
} finally {
postReadCleanup();
}
}
1. Cherche d'abord.table Existe - t - il déjà dans le qui n'a pas été recyclé 、Pas du tout.expireDeentry,Si vous trouvez,Et dansCacheBuilderConfiguré dansrefreshAfterWrite, Et l'intervalle de temps actuel a fonctionné sur cet événement , Recharger la valeur ,Sinon, Renvoie directement la valeur originale
2. Si on trouveValueReference- Oui.LoadingValueReference, Attendez que LoadingValueReferenceFin du chargement, Et renvoie la valeur chargée
3. Si vous ne trouvez pasentry, Ou trouvé entryLa valeur denull, Après la fermeture ,Continue.table La recherche existe déjà keyCorrespondantentry, Si trouvé et correspond à entry.isLoading()Pourtrue, Indique qu'un autre thread est chargé , Alors attendez que ce thread soit chargé , Si vous trouvez un non nullValeur,Renvoie la valeur,Sinon, créez unLoadingValueReference
Et appelleloadSync Charger les valeurs appropriées
Une fois le chargement terminé, Mettre à jour la valeur nouvellement chargée à tableMoyenne, C'est - à - dire, dans la plupart des cas, remplacer l'original LoadingValueReference
Voici les ressources d'apprentissage de Xiao Bian.,Il s'agit notamment de“Moyenne et supérieureJavaDévelopper des notes pour les questions d'entrevue à haute fréquence300Dow..pdf”Et“JavaNotes sur le système de connaissances de base.pdf”Partage de fichiers,Riche en contenu,**Oui.JVM、Verrouillage、Concurrence、Java
《Grandes usines de première ligneJavaAnalyse des questions d'entrevue+Notes d'apprentissage pour le développement de l'arrière - plan+La dernière vidéo d'architecture+Document d'information sur le code source du projet en direct》
【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 Partage open source du contenu complet
Réflexe、SpringPrincipes、Microservices、Zookeeper、Base de données、Beaucoup de points de connaissance tels que la structure des données.En même temps,JavaCarte cérébrale des notes de connaissances pour l'apprentissage avancé(Contient beaucoup de notes d'apprentissage)!**
Le tri des données n'est pas facile,Les Amis lecteurs peuvent partager!
JavaNotes sur le système de connaissances de base.pdf
Moyenne et supérieureJavaDévelopper des notes pour les questions d'entrevue à haute fréquence300Dow..pdf
Architecture Advanced interview Topic and Architecture Learning notes Brain graph
JavaArchitecture Advanced Learning Video Sharing
Cet article a été publié par CODINGProjet Open Source:【Grandes usines de première ligneJavaAnalyse des questions d'entrevue+Résumé de base notes d'étude+Dernière vidéo d'explication+Code source du projet opérationnel】Inclus