ConcurrentHashMap<Long, CopyOnWriteArrayList<Observation>
mostRecentObservationDB = new ConcurrentHashMap<Long,
CopyOnWriteArrayList<Observation>(524288, 0.75f, 32);
Ceci est ma carte. J'essaye de lire et d'écrire avec plusieurs threads en même temps, mais d'une façon ou d'une autre il crée toujours plusieurs clés. Seperate Thread, qui filtre cette table de hachage en supprimant les clés de plus de 10 secondes.Les threads mulitples essayent d'écrire en millisecondes comme clé, mais au lieu d'une clé, beaucoup de clés sont créées dans ConcurrentHashMap
while (true) {
try {
Thread.sleep(4000);
if(/*Time (key) older than 10 seconds*/) {
mostRecentObservationDB.remove(key);
}
} catch (Exception e) {
}
}
Le problème est qu'après avoir supprimé la clé, il crée plusieurs clés lors de l'initialisation. Ce sont mes journaux.
key -> 1501779153776, value
key -> 1501779153826, value
key -> 1501779153876, value
key -> 1501779153896, value
Je veux qu'ils soient stockés comme une seule clé lors de la suppression de l'opération. C'est comme ça que ça devrait être stocké.
key -> 1501779153776, value
Cependant, quand je lis de lui et puis supprimer toutes les entrées par remove()
méthode, je veux qu'aucun autre thread écrit à la carte pendant que je suis en train de lire le contenu de carte et de les supprimer.
C'est le code qui comporte étrange:
public static void main(String[] args) {
ConcurrentHashMap<Long, String> tenSecondBucket =
new ConcurrentHashMap<Long, String>();
Thread writingThread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1);
if(tenSecondBucket.size() > 0) {
// getting last key
long lastKey = 0;
for (long keyValue : tenSecondBucket.keySet()) {
lastKey = keyValue;
}
if(System.currentTimeMillis() - lastKey > 10000) {
tenSecondBucket.put(System.currentTimeMillis(), "secondEntry");
} else {
tenSecondBucket.put(lastKey, "updatedEntry");
}
} else {
tenSecondBucket.put(System.currentTimeMillis(), "newEntry");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
writingThread.start();
Thread removingThread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(4000);
if(tenSecondBucket.size() > 0) {
tenSecondBucket.keySet().stream().forEach(key -> {
if(System.currentTimeMillis() - key > 10000) {
tenSecondBucket.remove(key);
}
});
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
removingThread.start();
Thread readingThread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(4000);
if(tenSecondBucket.size() > 0) {
tenSecondBucket.keySet().stream().forEach(key -> {
System.out.println("testing key which is timestamp " + key);
});
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
readingThread.start();
}
Vous pouvez utiliser [l'opérateur de diamant] (https://stackoverflow.com/questions/4166966/what-is-the-point-of-the-diamond-operator-in-java-7) pour raccourcir significativement cette déclaration, comme vous le faites pour 'initializingObservation'. – Michael
Pouvez-vous fournir un [mcve]? Vous n'avez montré que la partie de votre code qui ajoutera (supposément) une nouvelle entrée toutes les 10 secondes - en fonction de ce code, on s'attendrait à voir plusieurs clés dans votre carte ... – assylias
@assylias J'espère que vous comprenez avec cette explication . Le problème est lors de la suppression de la clé, qui est plus de 10 secondes, les autres threads viennent et vérifie et pense qu'il n'y a pas d'entrée et essayer de créer une nouvelle entrée en même temps. Donc, à la fin, j'ai plusieurs clés et les valeurs séparées par des clés multiples inutiles au lieu d'une clé. Mon but est de capturer toutes les 10 secondes quelques observations en comparant leur valeur temporelle. –