【问题标题】:Multithreaded access to add, get, remove methods, using recursion and Java and a Tree structure多线程访问添加、获取、删除方法,使用递归和 Java 和树结构
【发布时间】:2012-11-02 12:50:34
【问题描述】:

我有一个树结构,我正在尝试使用递归方法来添加、获取或删除项目。我希望能够为使用迭代器找到的每个子节点引入一个新线程。我目前在调用它时将节点传递给递归方法。我希望能够启动一个线程并告诉该线程调用该方法。我将如何做类似于说新线程 thread.callMethod() 的事情?我显然需要一个 Runnable 接口和一个运行方法?然而,这似乎使事情变得比必要的复杂得多(我已经有了方法名称)。有谁知道使用 run(..) 的好方法,或者有谁知道不使用 run(..) 的更好方法。谢谢。

感谢您的回答。我一直在想我需要获得一个在新线程上运行的节点的新实例,但事实并非如此。节点只占用内存空间,线程引用了在内存中的实例上执行的方法代码(我的 CS 302 TA 在我的脑海中已经不同意我的看法)。所以..我一直在考虑枚举,但我在想我可能需要在实例化期间以某种方式让我的所有节点在单独的线程上运行,或者让方法实际编写在实现可运行的新类中。

换句话说,

public class TreeMethods implements Runnable
{
...
    run(.. node, .. params, .. enum)
    {
        switch(enum)
        case(add)
        {
             myThreadInstanceMethod(node);
        }
    ...
    }
    myThreadInstanceMethod(..) {..}
}

谢谢。我不知道我在问这个问题,但是您大大简化了我的线程管理设计过程。

【问题讨论】:

  • 多线程和从树中删除数据听起来像是同步的噩梦。还要考虑太多的线程不会很好地并行工作。
  • 据我所知,没有同步。每个实例只有一个线程,最大值。唯一的问题是启动该方法的线程必须等待它开始完成的所有线程。但是,它应该等待每个方法调用的返回值。因此,如果我可以通过某种方式等待()、睡眠()或加入()主线程,则无需保持上下文切换,直到实际产生返回值“i”。

标签: java multithreading data-structures recursion tree


【解决方案1】:

你可能需要这样的东西:

您的可运行文件:

public class ComputeNode implements Runnable {

    private Node node;

    public ComputeNode(Node nodeToCompute) {
        this.node = nodeToCompute;
    }

    @Override
    public void run() {
        computeOnNode(node);
    }
}

如何开始:

Runnable compute = new ComputeNode(nodeToComputeOn);
Thread t = new Thread(comute);
t.start();

ComputeOnNode() 是你自己写在某处的方法。

【讨论】:

  • 谢谢,但是在传入的节点上调用实例方法是更好的答案。
【解决方案2】:

如果没有 RunnableCallable 对象,您将无法做到这一点。做你想做的事情的正确方法是创建一个Runnable 类,它接受你的对象并调用该对象的适当方法。

public class MyRunnable implements Runnable {
    private MyObject obj;
    public MyRunnable(MyObject obj) {
       this.obj = obj;
    }
    public void run() {
       obj.someMethod();
    }
}

如果您需要调用几个方法之一,那么您可以为此使用enum。如果你需要传入参数,那么你可以将它们添加到构造函数中。

对于线程,始终建议您使用Executors 类和ExecutorService 线程池。这将限制递归算法创建的线程数,并隐藏线程详细信息。

// create a thread pool with 10 workers
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// or you can create an open-ended thread pool
// ExecutorService threadPool = Executors.newCachedThreadPool();
while (recursing) {
    threadPool.submit(new MyRunnable(myObject));
}
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
...

【讨论】:

  • 感谢您提供有关 Executor 服务的额外信息。对于 Tree 的大型实例,不使用 executor 服务可能会使线程数量过大。
  • 我正在阅读一本名为“企业中的持久性:持久性技术指南”(2008 年,IBM 出版社)的书。我看到你创作了 ORMLite。我觉得很有趣。稍后我可能会阅读代码示例和 api。谢谢。
猜你喜欢
  • 1970-01-01
  • 2012-10-22
  • 1970-01-01
  • 1970-01-01
  • 2011-01-31
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多