首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确使用共享BlockingQueue?

如何正确使用共享BlockingQueue?
EN

Stack Overflow用户
提问于 2013-12-20 18:17:06
回答 1查看 97关注 0票数 1

我有一个二叉树,其中每个节点代表一个电子门(和,OR,.)。我的任务是计算树的总价值(就像图片中的这个二叉树):

到目前为止,这是我的代码(没有线程实现):

gate_node:

代码语言:javascript
复制
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);
    }
}

预报员:

代码语言:javascript
复制
public abstract class Oprtator {
    abstract int calc(int x, int y);
}

代码语言:javascript
复制
public class and extends Oprtator {
    public int calc(int x, int y){
        return (x&y);
    }
}

代码语言:javascript
复制
public class or extends Oprtator {
    public int calc(int x, int y){
        return (x|y);
    }
}

树:

代码语言:javascript
复制
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
    }
}

主班

代码语言:javascript
复制
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);
    }
}

我想使用线程池来计算它,就像这样的算法:

制备:

  1. 将每个门实现为类/对象。它必须有两个属性:输入A、输入B和计算结果的方法;
  2. 实现一棵树。每个节点都是一对(门,next_node)。根是一个节点,next_node为空。叶子是这样的节点,以至于没有其他节点指向它。
  3. 使用节点的共享(线程安全)队列。最初是空的。
  4. 线程有一个固定的数目(选择一个,不依赖于门的数目),这些线程一直在等待队列中的一个元素(除非达到了结果,在这种情况下,它们只是退出)。

循环:

  1. 每当输入发生在节点上时,将节点放在队列中(在开始时,输入转到leaves)。这可以通过在门上定义add_input方法来实现。
  2. 线程从队列中拾取节点:
    1. 如果其中一个输入丢失,则丢弃它(当第二个输入出现时,它还会再出现一次)。另一个想法是,只有当两个输入都存在时,才能将节点放在队列中。
    2. 如果两个输入都在那里,则计算结果,如果它不是null,则将其传递给next_node (并将next_node放在队列中)。如果next_node为null,那么这就是您的结果--中断循环并完成。

唯一的问题是,我不知道如何创建共享的BlockingQueue,树中的每个节点对象都可以将自己插入其中,以及如何创建一个由固定大小的线程组成的数组,不断等待队列中的新元素可用(然后执行它们)……直到将头从列表中删除(这意味着我们已经计算完毕)。

我在网上搜索了BlockingQueue示例,但我只找到了生产者和消费者示例,而且我很难移动这些示例以适应我的问题。如果有人能帮我,我会很感激的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-12-20 18:25:24

我可以给你一些开始的指点,让你开始:)

要创建线程,只需生成以下多个线程:

代码语言:javascript
复制
for (int i=0;i<MAX_THREADS;i++) {
    new Thread(myRunnable).start();
}

您很可能希望存储对这些线程的引用,但它不是必需的。线程不需要特殊的设置,因为它们都是相同的,它们都只是坐在那里抓取队列中的项目。

要共享阻塞队列,最简单的方法就是使其成为静态和最终的:

代码语言:javascript
复制
static final BlockingQueue blockingQueue();

现在所有线程都可以访问它。

顺便说一句,如果我这样做,我根本不会使用队列,我会使用一个ThreadPoolExecutor,只需将处理作为新的可运行项发送到该队列。

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20709660

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档