2013-12-21 21 views
1

我的工作实现了代表电动马戏团(没有任何圈子,在这个图片)树生产者 - 消费者模式deisgn问题

i.e.

我使用这个实现:

Binary_Oprtator

public abstract class Binary_Oprtator { 
     abstract int calc(int x, int y); 

     @Override 
     public String toString() { 
     return super.toString().substring(0, super.toString().indexOf('@')); 
     } 
} 

与门

public class and extends Binary_Oprtator { 
     public int calc(int x, int y){ 
      return (x&y); 
     } 
} 

或门

public class or extends Binary_Oprtator { 
     public int calc(int x, int y){ 
      return (x|y); 
     } 
} 

gate_node

public class gate_node { 
    gate_node father_c; 
    gate_node right_c, left_c; 
    Binary_Oprtator op; 
    int value; 
    int right_v, left_v; 
    int array_index; 
    int arr_size; 
    boolean leaf; 
    boolean isRightChild; 

    public gate_node(Binary_Oprtator op, int array_index, int arr_size, boolean right) { 
     this.array_index = array_index; 
     this.arr_size = arr_size; 
     this.left_c = null; 
     this.right_c = null; 
     this.op = op; 
     right_v = left_v = -1; 
     this.leaf = false; 
     this.isRightChild = right; 

    } 

    void set_left_son(Binary_Oprtator op) { 
     this.left_c = new gate_node(op, array_index, arr_size/2,false); 
     this.left_c.father_c = this; 
     this.left_c.leaf = false; 
     this.left_c.isRightChild = false; 
    } 

    void set_right_son(Binary_Oprtator op) { 
     this.right_c = new gate_node(op, array_index + arr_size/2, 
       arr_size/2,true); 
     this.right_c.father_c = this; 
     this.right_c.leaf = false; 
     this.right_c.isRightChild = true; 
    } 

    void set_left_son_as_leaf(Binary_Oprtator op) throws InterruptedException { 
     this.left_c = new gate_node(op, array_index, arr_size/2,false); 
     this.left_c.father_c = this; 
     this.left_c.leaf = true; 
     this.left_c.left_v = main_class.arr[array_index]; 
     this.left_c.right_v = main_class.arr[array_index + 1]; 
     this.left_c.isRightChild = false; 

     main_class.queue.put(this.left_c); 
    } 

    void set_right_son_as_leaf(Binary_Oprtator op) throws InterruptedException { 
     this.right_c = new gate_node(op, array_index + arr_size/2, 
       arr_size/2,true); 
     this.right_c.father_c = this; 
     this.right_c.left_v = main_class.arr[array_index + 2]; 
     this.right_c.right_v = main_class.arr[array_index + 3]; 
     this.right_c.leaf = true; 
     this.right_c.isRightChild = true; 

     main_class.queue.put(this.right_c); 
    } 

    gate_node get_left() { 
     return this.left_c; 
    } 

    gate_node get_right() { 
     return this.right_c; 
    } 

    int compute() { 
     /* 
     * The following use of a static sInputCounter assumes that the 
     * static/global input array is ordered from left to right, irrespective 
     * of "depth". 
     */ 
     final int left, right; 
     if (this.left_c.leaf != true) { 
      left = this.left_c.compute(); 
     } else { 
      left = this.left_c.op.calc(this.left_c.left_v, this.left_c.right_v); 
     } 
     if (this.right_c.leaf != true) { 
      right = this.right_c.compute(); 

     } else { 
      right = this.right_c.op.calc(this.right_c.left_v, 
        this.right_c.right_v); 
     } 

     return op.calc(left, right); 
    } 

    int compute_with_print() { 
     /* 
     * The following use of a static sInputCounter assumes that the 
     * static/global input array is ordered from left to right, irrespective 
     * of "depth". 
     */ 

     final int left, right; 
     System.out.print(this.op + "("); 

     if (null != this.left_c) { 
      left = this.left_c.compute_with_print(); 
      System.out.print(","); 
     } else { 
      left = main_class.arr[array_index]; 
      System.out.print(left + ","); 
     } 

     if (null != this.right_c) { 
      right = this.right_c.compute_with_print(); 
      System.out.print(")"); 
     } else { 
      right = main_class.arr[array_index + 1]; 

      System.out.print(right + ")"); 
     } 

     return op.calc(left, right); 
    } 

} 

public class tree { 
    gate_node head; 

    public tree(Binary_Oprtator op,int array_index,int arr_size) { 
     this.head = new gate_node(op,array_index,arr_size,true); 
     head.father_c=null; 

    } 
    void calc_head_value(){ 
     int t_value = head.op.calc(head.left_v,head.right_v); 
    /* System.out.println(head.left_v+" "+head.op.toString()+" "+head.right_v+" = "+head.op.calc(head.left_v,head.right_v)); 
*/  head.value = t_value; 
    } 
    int compute() { 
     return head.compute(); 
    } 
    int compute_with_print(){ 
     return head.compute_with_print(); 
    } 



    void set_left_son(Binary_Oprtator op){ 
     head.left_c = new gate_node(op,head.array_index,head.arr_size/2,false); 
     head.left_c.father_c=head; 

    } 

    void set_right_son(Binary_Oprtator op){ 
     head.right_c = new gate_node(op,head.array_index + head.arr_size/2,head.arr_size/2,true); 
     head.right_c.father_c=head; 

    } 

    void set_right_son_as_leaf(Binary_Oprtator op) throws InterruptedException { 
     head.right_c = new gate_node(op,head.array_index,head.arr_size/2,false); 
     head.right_c.father_c=head; 
     head.right_c.father_c = head; 
     head.right_c.left_v = main_class.arr[head.array_index + 2]; 
     head.right_c.right_v = main_class.arr[head.array_index + 3]; 
     head.right_c.leaf = true; 
     head.right_c.isRightChild = true; 

     main_class.queue.put(head.right_c); 
    } 

    void set_left_son_as_leaf(Binary_Oprtator op) throws InterruptedException { 
     head.left_c = new gate_node(op, head.array_index, head.arr_size/2,false); 
     head.left_c.father_c = head; 
     head.left_c.leaf = true; 
     head.left_c.left_v = main_class.arr[head.array_index]; 
     head.left_c.right_v = main_class.arr[head.array_index + 1]; 
     head.left_c.isRightChild = false; 

     main_class.queue.put(head.left_c); 
    } 

    gate_node get_left(){ 
     return head.left_c; 
    } 

    gate_node get_right(){ 
     return head.right_c; 
    } 

} 

MAIN_CLASS

import java.util.concurrent.ArrayBlockingQueue; 
import java.util.concurrent.BlockingQueue; 

public class main_class { 
    public static int arr[] = { 1, 0, 0, 0, 1, 0, 0, 1 }; 

    static final BlockingQueue<gate_node> queue = new ArrayBlockingQueue<>(6); 

    public static void main(String[] args) throws InterruptedException { 

/************************************* 
* compute using multi threads 
************************************/ 
     System.out.println("compute using Multi threading"); 

     //start a consumer... wait for nodes to be insert into the queue 
     Consumer consumer = new Consumer(); 
     consumer.start(); 


     tree t = new tree(new and(), 0, arr.length); 
     t.set_left_son(new or()); 
     t.get_left().set_left_son_as_leaf(new and()); 
     t.get_left().set_right_son_as_leaf(new or()); 

     t.set_right_son(new and()); 
     t.get_right().set_left_son_as_leaf(new or()); 
     t.get_right().set_right_son_as_leaf(new or()); 

     consumer.join(); 
     t.calc_head_value(); //calc the head 
     System.out.println("The result is: " + t.head.value); 
     System.out.println(); 


    /****************************** 
    * compute with a single thread 
    ********************************/ 

     System.out.println("compute with a single thread"); 
     int res = t.compute(); 
     System.out.println("The result is: " + res); 


    /*********************************************** 
    * printing a arithmatic expression of the tree 
    *************************************************/ 
     System.out.println(); 
     t.compute_with_print(); 






    } 
} 

消费呃

import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class Consumer extends Thread { 

    Consumer() { 

    } 

    @Override 
    public void run() { 
     gate_node temp; 

     // the threads pool parts 
     ExecutorService executor = Executors.newFixedThreadPool(4); 

     try { 
      while ((temp = main_class.queue.take()).father_c != null) { 
       Runnable worker = new computingThread(temp); 
       executor.execute(worker); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     executor.shutdown(); 
     while (!executor.isTerminated()) { 
     } 

    } 

} 

computingThread

public class computingThread implements Runnable { 
    gate_node head; 

    int t_value; 

    public computingThread(gate_node head) { 
     this.head = head; 
     this.t_value = -1; 
    } 

    @Override 
    public void run() { 
     /* System.out.println("Start: "+this.hashCode()); */ 
     t_value = head.op.calc(head.left_v,head.right_v); 

/*  System.out.println("thread: "+this.hashCode()+" is running ==> "+head.left_v+" "+head.op.toString()+" "+head.right_v+" = "+head.op.calc(head.left_v,head.right_v)); 
*/  head.value = this.t_value; 

     // update the father 

     if (head.isRightChild == true) { //update right fathers entire 
      head.father_c.right_v = t_value; 

      /*System.out.println("isRightChild");*/ 
     } else { //update left fathers entire 
      head.father_c.left_v = t_value; 
     } 

     if ((head.father_c.right_v != -1) && (head.father_c.left_v != -1)){ //father is ready to compute-> to the queue! 
      try { 
       main_class.queue.put(head.father_c); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      } 
    /* try { 
      Thread.sleep(1); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     }*/ 
    /* System.out.println("thread: "+this.hashCode()+" is done!"); 
*/  return; 
    } 
} 

在这里我想要做的事:

我尝试这样做,使用多线程计算树的有限值(parllel COMPUT每个节点获得两个值,根据他的操作者产生结果,并将其传递到树上,直到根节点结束为止)。我所做的是设置一个固定数量的空间队列。

我在构建树时将叶子插入到队列中。然后我开始一个消费者,每个叶子都要收集,计算它,将结果传递给他父亲的正确信息,并且当两个entreis都插入父节点时,它也会进入队列,依此类推......直到根被cacluted)。

唯一的问题是我不能使用树中叶子数量较小的队列,我不知道为什么。

可能是因为我正在构建树时我将叶子插入到树中,如果队列比叶子小,我在做一个:main_class.queue.put(this.right_c);当队列已满时,并且导致progrem等到队列中的空间将被释放,这不会发生(因为我还没有启动线程)。

有没有人有任何解决方案?

和另一个问题?那是考虑一个parrlel计算?这意味着如果我设置了一个大小为2的队列,这是否意味着我只用两个线程来完成所有的计算(因为我想设置的就像某台计算机的核心CPU数量)。

感谢和抱歉我的拼写错误。

+0

您的代码不容易阅读。所以就在第一次快速扫描时,主线程旁边只有一个线程。这不是真正的并行编程,所以处理以串行方式运行。我想这会导致你的问题。 – JosefN

回答

0

我认为你以比需要的更复杂的方式对它进行建模。我不会将我的建模基于树。电路并不总是一棵树。你可以有多个节点作为电路输出,对吧?

我会基于我的建模在门节点上。我会有一个Gate类与两个输入和一个输出。输入和输出将是GateValue类型。如果门是andor门,输出将使用不同的方式计算。

然后我会结合他们建立我的电路,像这样:

gate1.Input1 = gate2.Output 
gate1.Input2 = gate3.Output 

然后,我会计算最后门的值(整个电路的输出),这将导致其他大门来计算它们的值。这样,你就不需要一个“并行”的计算机制。只要你的电路中没有反馈回路,这就可以正常工作。

希望我帮了忙!