java中不可变树的多线程构造算法

时间:2011-02-12 10:51:08

标签: java multithreading algorithm immutability

我想构建一个 immutable 树数据结构,表示filsystem目录结构的任意子集。通常会有一个过滤器知道包含/排除,我基本上希望在构造中有一些线程支持。

这听起来像编写自己的纯粹书呆子乐趣,但我实际上想知道这个主题是否有任何好的例子,文本或类似内容?源代码很好;)

5 个答案:

答案 0 :(得分:1)

答案 1 :(得分:0)

我不知道这是否有用。 Java SortedMap使用红黑树,你可以在这里查看源代码。

 https://www.docjar.com/html/api/org/eclipse/ant/internal/ui/dtd/util/SortedMap.java.html

对于不可修改的SortedMap。你可以在这里看到Collections.unmodifiableSortepMap的源代码

http://www.docjar.com/html/api/java/util/Collections.java.html

答案 2 :(得分:0)

我建议维护一个“工作项目”队列。每个工作项都封装一个要探索的目录,以及一个将生成的树节点附加到的现有父节点(如果有)。每个线程在循环中执行,从队列前面拉出项目,执行它们,并将任何子目录作为新工作项推送到队列末尾。

通过将根目录(没有父树节点)作为第一个工作项来启动该过程。当队列为空,并且所有线程都空闲/等待时,该过程结束。

以上假设树一旦构造就是不可变的,但在构造过程中是可变的。如果不是这种情况,则需要构建树“自下而上”,因此您需要一个临时的,可变的结构来保存节点,因为它们被追加。否则,过程应该是相同的。

答案 3 :(得分:0)

致krosenvold:

我认为你没有理解我的意图。也许我应该让自己更清楚。

假设Tree和TreeBuilder在同一个包中。

正如您所见,Tree构造函数和freeze()方法具有级别访问权限。所以你不能在包外面创建它,也不能在包外面冻结它。

唯一的方法是通过build()方法。只有TreeBuilder可以使用同步的构建方法创建Tree。

现在我甚至意识到你甚至可以更简单地删除readonly标志并将Tree.addChild()方法更改为包可见性。因此,您将获得一个没有公共mutators的树只有访问者。

就像我说Tree没有同步。 TreeBuilder是您进行同步的地方。仔细查看访问器和更改器。查看public和package修饰符所在的位置,您将看到修改树的唯一方法是当您在同一个包中时,只有树构建器才能执行此操作。

public class Tree<T extends Filterable>{
   private final T data;
   private Tree<T> parent;
   private List<Tree<T>> children;
   private List<FilterChain<T>> filterChain;
   private boolean readonly = false;  
   /*package*/ Tree(T data) {...} 
   /*package*/ Tree(Tree<T> parent, T data) {...}

   /*package*/ void addChild(Tree<T> child){
       children.add(child);
   }
   public List<?> getResults(){
       return data.returnResults(filterChain);
   }

}

public class TreeBuilder<T>{
  public synchronized TreeNode createRoot(T data);
  public synchronized void addSubElement(TreeNode parentNode ,T data);
  public synchronized void addFilter(TreeNode node, Filter<T> filter);
  public Tree<T> synchronized build(){
     Tree<T> tree= ... 
     //build your tree
     //build filter chain for specific tree node
     return tree;
  }

}

答案 4 :(得分:-1)

嗨我不知道你想要什么,特别是在线程安全方面,但也许在伪代码下可以用作草案。

public interface Filterable {
     List<?> returnResults(FilterChain chain);
} 

public class Tree<T extends Filterable>{
   private final T data;
   private Tree<T> parent;
   private List<Tree<T>> children;
   private List<FilterChain<T>> filterChain;
   private boolean readonly = false;  
   /*package*/ Tree(T data) {...} 
   /*package*/ Tree(Tree<T> parent, T data) {...}

   //freeze mtd makes object read-only
   /*package*/ void freeze(){         
          readonly = true;
      for(Tree<T> child: children){
          child.freeze();
      }
   }
   public void addChild(Tree<T> child){
       if(readonly){
           throws new NonModifiableException(...);
       }
       children.add(child);
   }
   public List<?> getResults(){
       return data.returnResults(filterChain);
   }

}

您可以专注于在树的构建器上进行同步

,而不是在树上进行同步
public class TreeBuilder<T>{
    public synchronized TreeNode createRoot(T data);
    public synchronized void addSubElement(TreeNode parentNode ,T data);
    public synchronized void addFilter(TreeNode node, Filter<T> filter);
    public Tree<T> synchronized build(){
       Tree<T> tree= ... 
       //build your tree
       //build filter chain for specific tree node
       tree.freeze(); //make your tree readonly
       return tree;
    }
}