У меня есть двоичное дерево, в котором каждый узел представляет собой электронные ворота (И, ИЛИ,...). Моя миссия состоит в том, чтобы вычислить общее значение дерева (как это на картинке, бинарное дерево):

Это мой код до сих пор (без реализации потоков):
ворота_узел:
public class gate_node {
gate_node right_c, left_c;
Oprtator op;
int value;
int right_v, left_v;
public gate_node(gate_node right, gate_node left, Oprtator op) {
this.left_c = left;
this.right_c = right;
this.op = op;
right_v = left_v = 0;
}
void add_input(int right_v, int left_v){
this.right_v=right_v;
this.left_v=left_v;
}
int compute(int array_index, int arr_size) {
/*
* 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(array_index,arr_size/2);
System.out.print(",");
} else {
left = main_class.arr[array_index];
System.out.print(left + ",");
}
if (null != this.right_c) {
right = this.right_c.compute(array_index + arr_size/2,arr_size/2);
System.out.print(")");
} else {
right = main_class.arr[array_index + 1];
System.out.print(right + ")");
}
return op.calc(left, right);
}
}
Оператор:
public abstract class Oprtator {
abstract int calc(int x, int y);
}
И
public class and extends Oprtator {
public int calc(int x, int y){
return (x&y);
}
}
Or
public class or extends Oprtator {
public int calc(int x, int y){
return (x|y);
}
}
Дерево:
public class tree implements Runnable {
gate_node head;
tree(gate_node head) {
this.head = head;
}
void go_right() {
head = head.right_c;
}
void go_left() {
head = head.left_c;
}
@Override
public void run() {
// TODO Auto-generated method stub
}
}
основной класс
public class main_class {
public static int arr[] = { 1, 1, 0, 1, 0, 1, 0, 1 };
public static void main(String[] args) {
tree t = new tree(new gate_node(null, null, new and()));
t.head.right_c = new gate_node(null, null, new or());
t.head.right_c.right_c = new gate_node(null, null, new and());
t.head.right_c.left_c = new gate_node(null, null, new and());
t.head.left_c = new gate_node(null, null, new or());
t.head.left_c.right_c = new gate_node(null, null, new and());
t.head.left_c.left_c = new gate_node(null, null, new and());
int res = t.head.compute(0, arr.length);
System.out.println();
System.out.println("The result is: " + res);
}
}
Я хочу рассчитать его с помощью пула потоков, как этот алгоритм:
Подготовка:
Реализуйте каждый шлюз как класс/объект. Он должен иметь 2 атрибута: ввод A, ввод B и способ вычисления результата;
Реализовать дерево. Каждый узел представляет собой пару (gate, next_node). Корень — это узел, для которого next_node имеет значение null. Листья — это узлы, на которые не указывает ни один другой узел.
Используйте общую (потокобезопасную) очередь узлов. Он изначально пустой.
Существует фиксированное количество (выберите одно, не зависит от количества шлюзов) потоков, которые постоянно ожидают элемента из очереди (если результат не достигнут, в этом случае они просто завершают работу).
Цикл:
Всякий раз, когда на узле происходит вход, поместите узел в очередь (в начале входы идут к листьям). Это можно просто реализовать, определив метод add_input для ворот.
Поток берет узел из очереди:
Если один из входов отсутствует, отбросьте его (он появится еще раз, когда появится второй вход). Другая идея состоит в том, чтобы поместить узел в очередь только при наличии обоих входов.
Если есть оба входа, то вычислите результат и передайте его в next_node, если он не нулевой (и поместите next_node в очередь). Если next_node имеет значение null, то это ваш результат — прервите цикл и завершите.
единственная проблема в том, что я не знаю, как создать разделяемую BlockingQueue, чтобы каждый объект-узел в дереве мог вставить себя в нее, и как создать массив потоков фиксированного размера, который постоянно ожидает новых элементов в очереди для быть доступными (а затем выполнять их)..... до тех пор, пока голова не будет удалена из списка (это означает, что мы закончили вычисления).
Я искал в Интернете примеры BlockingQueue, но нашел только примеры производителей и потребителей, и мне трудно переместить эти примеры в соответствии с моей проблемой. Я был бы очень признателен, если бы кто-нибудь мог попытаться мне помочь.