Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 制作人–;消费者模式设计问题_Java_Multithreading_Algorithm_Producer Consumer - Fatal编程技术网

Java 制作人–;消费者模式设计问题

Java 制作人–;消费者模式设计问题,java,multithreading,algorithm,producer-consumer,Java,Multithreading,Algorithm,Producer Consumer,我正在制作一棵代表电气马戏团的树(没有任何圆圈,如图所示) 我使用这个实现: 二进制运算器 public abstract class Binary_Oprtator { abstract int calc(int x, int y); @Override public String toString() { return super.toString().substring(0, super.toString().indexO

我正在制作一棵代表电气马戏团的树(没有任何圆圈,如图所示)

我使用这个实现:

二进制运算器

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);
        }
}
门节点

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);
    }

}

主课

   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();






    }
}
计算线程

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;
    }
}
下面是我想做的:

我正在尝试进行并行计算,使用多线程计算树的有限值(每个节点获得两个值,根据其运算符生成结果,在树上传递..直到根被计算)。我所做的是设置一个固定数量的空间队列

我在构建树时将叶子插入队列。然后,我启动一个消费者,对每个叶子进行计算,将结果传递到他父亲的右中心,当两个主菜都插入父亲节点时,它也会进入队列,以此类推。。直到根被拔出)

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

可能是因为在构建树时,我正在将叶子插入树中,如果队列比叶子小,我正在执行:
main\u class.queue.put(this.right\u c)当队列已满时,这会导致程序等待队列上的空间被释放,但这不会发生(因为我还没有启动线程)

有人有什么解决办法吗

还有一个问题?这是否算是一个PARRLL计算?也就是说,如果我设置一个大小为2的队列,这是否意味着我将只使用两个线程进行所有计算(因为我要设置的是某台计算机的核心CPU数量)


感谢并为我的拼写错误感到抱歉。

我想你用了一种比需要的更复杂的方式来建模。我不会把我的模型建立在一棵树上。一个电路,并不总是一棵树。可以有多个节点作为电路输出,对吗

我将基于gate节点进行建模。我有一个
类,有两个输入和一个输出。输入和输出的类型应为
GateValue
。如果门是
门,则输出将使用不同的方式计算

然后我会将它们结合起来构建我的电路,如下所示:

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

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


希望我能帮忙

你的代码不容易阅读。所以在第一次快速扫描中,除了主线程之外只有一个线程。它不是真正的并行编程,因此处理以串行方式运行。我想是它引起了你的问题。
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;
    }
}
gate1.Input1 = gate2.Output
gate1.Input2 = gate3.Output