【问题标题】:Java: Controlling hardware tasks with pausable ThreadPoolExecutorJava:使用可暂停的 ThreadPoolExecutor 控制硬件任务
【发布时间】:2018-01-20 09:43:37
【问题描述】:

我想实现一个单生产者 - 多消费者逻辑,其中每个消费者处理时间取决于硬件响应。

**编辑

我有一组对象(设备)。每个对象(device)对应一个我想在软件中模拟的硬件真实单元。 我的主类将任务列表分配给每个设备。每个任务都需要一定的时间才能完成——我想控制它,以模拟硬件操作。每个设备对象都有自己的SingleThreadExecutorService 服务执行器来管理自己的排队任务。特定设备对象任务上的Sleep不应干扰主设备对象或其他设备对象的性能。

到目前为止一切正常,但我不确定如何在不阻塞主线程的情况下从任务中获得未来(!future.isDone())。当我这样做时,会出现两个问题:

  • 任务 1 提交给device[ 1 ].executor。任务 1 休眠以模拟硬件操作时间。
  • 任务 2 应该在任务 1 提交后立即提交给device[ 2 ].executor,但它不会,因为主线程在等待任务 1 返回 Future。这个问题会在模拟中累积延迟,因为添加的每个任务都会导致下一个设备必须等待前一个设备完成,而不是同时运行。

橙色线表示强制设备等待 1000 毫秒的命令。 当 Future 返回时,它会向设备 2 提交一个新任务,但它已经晚了 1 秒,如蓝线所示。以此类推,绿线表示延迟增量。

如果我不使用 Future 来获取任务完成的时间,模拟似乎运行正确。我找不到使用 future.isDone() 的方法,而不必创建一个新线程来检查它。另外,如果有人能建议我在这种情况下如何进行,我会非常高兴。

【问题讨论】:

    标签: java multithreading thread-safety threadpoolexecutor


    【解决方案1】:

    如果您的目标是实现每个消费者任务在其任务处理期间与硬件设备对话的东西,那么该任务的run 方法应该简单地与设备对话并阻塞,直到它收到来自装置。 (您如何做到这一点取决于设备及其 API ...)

    如果您的目标是使用模拟设备执行上述操作(即用于测试目的),则让任务调用Thread.sleep(...) 来模拟设备响应所需的时间。 p>

    根据您的问题描述(据我了解),您找到的 PausableSchedulerThreadPoolExecutor 类将无济于事。该类所做的是暂停线程本身。全部。


    更新

    任务 2 应该在任务 1 提交后立即提交给 device[2].executor,但不会,因为在等待任务 1 返回 Future 时主线程处于暂停状态时间>。

    这是不正确的。 Future 对象在提交任务时立即返回。

    您的错误(可能)是主线程在Future 上调用get。那会阻塞。但关键是您的主线程实际上需要在提交下一个任务之前在Future 上调用get,那么它基本上是单线程的。

    真正的解决方案:弄清楚如何打破使您的应用程序成为单线程的依赖关系。 (但请注意:如果您将Future 作为参数传递给任务,则相应的工作线程可能会阻塞。除非您在线程池中有足够的线程,否则您最终可能会出现饥饿并降低并发性。)

    【讨论】:

    • 非常感谢您的回复。我对Thread.sleep(...) 还是有点困惑,我以为这会导致主线程休眠,不是吗?我的目标是单独暂停每个 Runnable 对象。我正在调试我的代码,并注意到每个可运行(在睡眠时)都在增加其他线程的一些延迟。但那是因为我在等待future.get() 时将主线程困在了一边。我想我需要编辑我的帖子以添加一些示例。
    • 那是个好主意。因为你说的对我来说没有多大意义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-20
    • 1970-01-01
    • 2015-03-26
    • 1970-01-01
    • 2018-07-04
    • 2014-09-21
    • 2012-06-23
    相关资源
    最近更新 更多