当前位置: 首页 > 面试题库 >

Java并行处理;需要建议,例如在Runnanble / Callable接口上

赵永逸
2023-03-14
问题内容

假设我有一组对象需要用两种不同的方式进行分析,这两种方法都需要花费较长的时间并且涉及IO调用,所以我试图弄清楚如何/是否可以优化软件的这一部分。
,尤其是利用多个处理器(我以前使用的机器是8核i7,执行期间几乎永远不会超过10%的负载)。

我对并行编程或多线程技术还很陌生(不确定什么是正确的术语),因此我已经阅读了一些先前的问题,尤其是关注投票率高和信息量大的答案。我也正在阅读有关并发性的Oracle
/ Sun教程

到目前为止,这就是我的想法。

  • 线程安全的集合保存要分析的对象
  • 一旦集合中有对象(它们通过一系列查询一次出现),则每个对象启动一个线程
  • 每个特定的线程都负责初始的分析前准备工作;然后调用分析。
  • 这两个分析被实现为Runnables / Callables,因此在必要时由线程调用。

我的问题是:

  1. 这是一个合理的计划吗?如果不是,您将如何进行呢?
  2. 为了确保事情不会失控,我应该实现一个ThreadManager或类似的东西来启动和停止线程,并在线程完成时重新分配它们吗?例如,如果我有256个要分析的对象,总共16个线程,则ThreadManager会将第一个完成的线程分配给要分析的第17个对象,依此类推。
  3. 除了Callable可以返回结果这一事实之外,Runnable / Callable之间是否还有显着差异?否则,我应该尝试实现自己的接口,为什么?

谢谢,


问题答案:
  1. 您可以使用BlockingQueue实现来保存对象并从那里生成线程。该接口基于 生产者-消费者 原则。该认沽() ,直到有更多空间和方法将阻塞,如果你的队列已满取()如果直到有一些在队列中再次对象队列为空方法将阻塞。

  2. 一个ExecutorService的可以帮助你管理你的线程池。

  3. 如果您正在等待生成的线程的结果,那么可以使用 Callable 接口是一个好主意,因为您可以更早地开始计算,并以 Future -s中的结果来处理代码。至于与 Runnable 接口的区别,请 参见 Callable javadoc:

Callable接口与Runnable相似,两者均适用于其实例可能由另一个线程执行的类。 但是,Runnable不会返回结果,也不能引发已检查的异常

在寻求Java并发性时需要考虑的一些常规事项:

  • 事实 并非凭空而来。 volatile ,AtomicReference和 java.util.concurrent.atomic 软件包中的其他对象是您的朋友。
  • 您需要使用同步和锁定来仔细确保复合操作的 原子性


 类似资料:
  • 我正在上这门Android编程课,我现在要做一个项目。我的应用程序应该能够添加一些效果,如混响/回声/合唱/等。到音轨上。 我尝试使用PresetReverb和EnvironmentalReverb,但没有成功(应用程序运行,但没有应用任何效果)。 我也检查了这个解决方案,但不适合我。我在Genymotion虚拟设备Galaxy Nexus-4.3-API18和三星Galaxy Chat B533

  • 我有一个场景,其中我得到一个String消息列表,我必须遍历String并调用另一个方法,这是一个长时间运行的过程。然后我必须收集这个长时间运行过程的结果并连接结果并将其发送回用户交互界面。我对Scala中的这些未来概念很陌生。我正在使用Play框架,其中字符串列表将来自用户交互界面。这是我第一次尝试实现ht场景的样子: 为简单起见,long RunningCall将只返回一个字符串。稍后我将把它

  • 问题内容: 我们需要大量的序列化工作,并且必须在使用的每个对象上指定标签,这是一种负担。特别是当它是第三方类时,我们不能真正更改。 问题是:由于是一个空接口,并且Java一旦添加便提供了可靠的序列化 为什么它们不使所有内容都可序列化,仅此而已? 问题答案: 序列化充满陷阱。这种形式的自动序列化支持使类内部成为公共API的一部分(这就是javadoc为你提供类的持久化形式的原因)。 为了实现长期持久

  • 在Java中设计并发线程时,使用和接口有什么区别,为什么要选择其中一个?

  • 问题内容: 我知道callable的调用可能会将异常抛出给调用它的父方法,而runnable则不是这种情况。 我不知道如何,因为它是线程方法,并且是线程堆栈的最底层方法。 问题答案: 的要点是将异常抛出到调用线程,例如,当您获得提交的结果时。

  • 嘿,所以我为ExecutorService的java文档选择了这个例子。我想确认这个代码的流程,执行者。newFixedThreadPool将创建一个线程池(我猜)。所以serversocket将等待连接,一旦获得连接,就会启动一个线程,所以现在池大小减少1。一旦线程完成执行,池大小将再次增加1,不是吗?线程会放弃它使用的资源吗?