알고리즘에서 나는 특정 방법으로 배열을 블랙리스트에 올릴 수있는 블랙리스트 작성 메커니즘을 개발하려고했습니다. "1, 2, 3"이 "1, 2, 3" , 4, 5 "도 차단 목록에 포함됩니다.
나는 지금까지 생각해 낸 해결책에 대해 매우 만족합니다. 하지만 여러 스레드에서 블랙리스트에 액세스 할 때 심각한 문제가있는 것 같습니다. 배열에 블랙리스트가 없더라도 "contains"(아래 코드 참조) 메서드는 때때로 true를 반환합니다. 하나의 스레드 만 사용하는 경우이 문제는 발생하지 않으므로 동시성 문제가 발생할 가능성이 큽니다.
일부 동기화를 추가하려고했지만 아무 것도 변경하지 않았습니다. 나는 또한 java.util.concurrent 클래스를 사용하여 약간 다른 구현을 시도했다. 이 문제를 해결하는 방법에 대한 아이디어가 있습니까?
배열의 동시성 문제 (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;
}
}
}
그것은 나에게 확인을 보이는 :이 같은 뭔가를 9000 이상 참조를 할당 할 필요가 없도록
여기에 내가는 HashMap을 사용합니다. 동기화는 모든 문제가 add와 contains를 동시에 호출하는 것을 방지해야합니다. 그래서 문제를 호출하는 코드에 문제가있는 것 같습니다. BTW, 동기화를 사용하면 노드의 변수를 휘발성으로 선언 할 필요가 없습니다. – starblue
나에게도 괜찮은 것처럼 보입니다. 변수가 유용 할 것으로 생각되어 변수가 휘발성이 있습니다. 그러나 그들이 휘발성이거나 그렇지 않다면 아무런 차이가없는 것으로 보인다. – Johannes
블랙리스트 방법이 공개 된 이유는 무엇입니까? 다른 스레드가이 스레드를 호출하지 않았습니까? – Istao