Pour un algorithme sur lequel je travaille, j'ai essayé de développer un mécanisme de liste noire qui peut blacklister des tableaux d'une manière spécifique: Si "1, 2, 3" est sur liste noire "1, 2, 3 , 4, 5 "est également considéré comme sur liste noire.
Je suis assez content de la solution que j'ai trouvée jusqu'à présent. Mais il semble y avoir de sérieux problèmes lorsque j'accède à une liste noire à partir de plusieurs threads. La méthode "contient" (voir le code ci-dessous) renvoie parfois la valeur true, même si un tableau n'est pas sur liste noire. Ce problème ne se produit pas si je n'utilise qu'un seul thread, il s'agit donc probablement d'un problème de concurrence.
J'ai essayé d'ajouter une synchronisation, mais cela n'a rien changé. J'ai également essayé quelques implémentations légèrement différentes en utilisant les classes java.util.concurrent. Des idées pour résoudre le problème?
Problème de concurrence avec les tableaux (Java)
public class Blacklist {
private static final int ARRAY_GROWTH = 10;
private final Node root = new Node();
private static class Node{
private volatile Node[] childNodes = new Node[ARRAY_GROWTH];
private volatile boolean blacklisted = false;
public void blacklist(){
this.blacklisted = true;
this.childNodes = null;
}
}
public void add(final int[] array){
synchronized (root) {
Node currentNode = this.root;
for(final int edge : array){
if(currentNode.blacklisted)
return;
else if(currentNode.childNodes.length <= edge) {
currentNode.childNodes = Arrays.copyOf(currentNode.childNodes, edge + ARRAY_GROWTH);
}
if(currentNode.childNodes[edge] == null) {
currentNode.childNodes[edge] = new Node();
}
currentNode = currentNode.childNodes[edge];
}
currentNode.blacklist();
}
}
public boolean contains(final int[] array){
synchronized (root) {
Node currentNode = this.root;
for(final int edge : array){
if(currentNode.blacklisted)
return true;
else if(currentNode.childNodes.length <= edge || currentNode.childNodes[edge] == null)
return false;
currentNode = currentNode.childNodes[edge];
}
return currentNode.blacklisted;
}
}
}
Il semble OK pour moi. La synchronisation devrait empêcher tous les problèmes d'appeler add et contient simultanément, donc je suppose que votre problème est sur le code qui les appelle. BTW, avec la synchronisation, vous n'avez pas besoin de déclarer les variables dans un nœud volatile. – starblue
Ça me va aussi :) Les variables sont juste volatiles parce que j'ai pensé que cela pourrait aider. Mais il semble ne faire aucune différence si elles sont volatiles ou non. – Johannes
Pourquoi la méthode de la liste noire est-elle publique? Êtes-vous sûr qu'aucun autre thread ne l'appelle? – Istao