對於我正在處理的算法,我試圖開發一個黑名單機制,可以以特定方式將數組列入黑名單:如果「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;
}
}
}
它看起來OK我。同步應該防止調用add和包含併發的所有問題,所以我想你的問題是在調用它們的代碼上。順便說一句,通過同步,你不需要在一個節點中聲明變量volatile。 – starblue 2010-05-29 18:14:24
它對我也很好:) 變量只是不穩定的,因爲我認爲它可能有幫助。但是,如果它們不穩定或者不穩定,它似乎沒有什麼區別。 – Johannes 2010-05-29 18:43:49
爲什麼黑名單方法是公開的?你確定沒有其他線程調用它嗎? – Istao 2010-05-29 19:18:50