从一个方法中移除阻塞

7

这是一份作业。

我不需要答案,只需要一些链接或想法。

简单来说,我想要做的是:

举个简单的例子:

public class Example
{
    public void method()
    {
           int x = doThat();
           //Call other methods which do not depend on x
           return;
    }
}
doThat()是一个已知需要耗费时间的方法,这会导致我的程序阻塞直到结果返回。我想要使用该对象的其他方法,但程序会在doThat()完成之前被frozen。这些不同的方法不一定要从本例中使用的method()中调用,也可以从对象外部调用。
我考虑使用线程,但如果我有大量对象(1000+),这可能不是很有效率(请纠正我如果我错了)。我猜如果我使用线程,我必须为每个对象使用一个线程?
除了线程之外,是否有其他方法可以使调用对象在调用doThat();时不被阻塞?如果线程是唯一的方法,您能提供一个链接吗?
知道像这样的问题会被downvote,我会接受任何downvotes。但请给我一个链接就好了。
预先感谢。我希望问题符合规定。
4个回答

3
我会为此使用线程,但我想补充一下,你可能会对java.util.concurrent.Executors(创建线程池以处理多个对象)以及java.util.concurrent.Futurejava.util.concurrent.Callable类感兴趣,它们可以启动能够返回值的线程。请查看并发教程以获取更多信息。

我的Common说只是将一个方法转化为线程是不可能的,所以如果我将类"Example"修改为线程,那么在"method()"阻塞期间调用该类的其他方法是否可行? - user418748
Example类不会变成一个线程。Example负责使用n个可能的线程(Executors.newFixedThreadPool(n))创建您的线程池,然后您将不得不创建自己的扩展“Callable”的类来完成工作(它们是您的线程)。 Callable.call() 的实现将完成工作(doThat())并返回计算结果。 通过ExecutorService.submit(callable)将Callables传递给线程池,并通过Future.get()检索结果。 请注意,此最后调用是阻塞的,您应该在返回之前执行它。 - Kellindil

1
我建议您创建一个实现Runnable接口的类,其中run方法执行与示例中的doThat()相同的操作。然后可以通过简单的方式在单独的线程中调用它。Java的Thread具有接受可运行对象的构造函数。使用runjoin方法。
祝好 Matthias

1
当然,线程是处理后台任务的唯一解决方案,但您不必仅仅为执行单个操作而强制使用一个线程。 您可以仅使用一个线程来维护要执行的操作队列,以使每次调用doThat方法都会向队列中添加一个新条目。 也许一些设计模式(如“策略”)可以帮助您将要执行的操作的概念泛化,以便将“操作对象”存储到线程的队列中。

1

您想要同时执行多个任务,因此使用线程确实是正确的方法。Java教程并发课程可能会对您有所帮助。

1000个并发线程将会产生沉重的内存负载,因为每个线程都会分配一定量的堆栈内存(2 MB?)。然而,如果您可以确保同一时间只有一个线程在运行,那么您仍然可以采用每个对象一个线程的方法。这将要求您管理doThat()仅在另一个对象上的前一个调用所产生的线程已经完成时才被调用。

如果您无法轻松确保这一点,另一种方法是构建一个工作线程,该线程从双端队列中读取要处理的对象。然后doThat()方法将只是将this添加到队列的末尾,工作线程稍后会提取它。在从并发线程访问任何数据结构时,必须正确同步。主线程应以某种方式通知工作线程条件,即它不会再向队列中添加任何对象,因此工作线程可以干净地终止。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接