【问题标题】:How can I create an "event-driven" background thread in Java?如何在 Java 中创建“事件驱动”后台线程?
【发布时间】:2011-10-26 01:26:13
【问题描述】:

我喜欢 invokeLater() 将工作单元发送到 AWT EDT 的简单性。最好有一个类似的机制来将工作请求发送到后台线程(例如 SwingWorker),但据我了解,这些没有任何类型的事件队列和调度机制,这正是 invokeLater() 所依赖的。

因此,我最终为我的后台线程提供了一个阻塞队列,其他线程向该队列发送消息,并且线程本质上运行一个接收循环,一直阻塞直到消息到达。

事实上,这可能正是人们在后台线程中实现类似 EDT 行为的方式(或者会这样吗?)。另一方面,我喜欢线程的简单性,它只是惰性地悬挂在那里,每当它们碰巧从天空中一些看不见的事件调度队列被调度到它时处理“工作液滴”。 Java 是否提供了一种方法来创建这种“事件驱动的工作线程”?或者消息队列到底是不是正确的方法?与此相关的是,invokeLater() 消息传递技术是否存在缺陷?

【问题讨论】:

    标签: java worker event-driven-design invokelater


    【解决方案1】:

    您应该查看 java.util.concurrent,更具体地说是 Executor's,它们通常只是一个可以处理如下请求的线程池:executor.execute(runnableTask);。如果您希望单个线程处理所有请求,请使用单个线程创建您的线程:executor = Executors.newSingleThreadExecutor()'。还有 ExecutorService 可以在任务完成时返回一个值。

    【讨论】:

    • 很高兴知道,但似乎没有提供我正在寻找的“调度”。
    • 在单线程执行器上发送可运行文件与在 EDT 上发送可运行文件完全相同。任务排队等待处理,如果没有当前作业,线程将保持活动状态。
    • @Chap 我正在阅读另一个答案的 cmets 中对您的问题的描述,看来单线程执行器正是您要寻找的。​​span>
    • 效果很好。执行者是一座金矿。感谢您指出这一点。
    【解决方案2】:

    Producer-Consumer Design Patter(这是您在阻塞队列中使用的)只是解决不同类别问题的不同方法; EDT 使用Worker Design Pattern。查看这两种设计模式,看看哪一种最适合您的需求。

    • 当您有多个线程分别执行独立任务时,通常使用生产者-消费者模式。
    • EDT 采用的 Worker 模式用于将 多个任务的结果汇集到单个线程(在本例中为 GUI 线程)。

    当然,如果您有一个队列和一个带有多个生产者的消费者,您可以采用生产者-消费者模式并实现与工人模式类似的行为,但这只是突出了设计模式的灵活性。因此,再次强调,选择设计模式是基于最适合您的特定情况的设计模式 - 当模式足够灵活以适应您想要的行为时,没有特别错误的选择。

    【讨论】:

    • 我的情况肯定需要 Worker 模式 - 我需要通过单个线程串行处理每个任务。但是,您链接到 SwingWorker - 我可能错过了重点,但是否有可能同时产生多个 SwingWorker 线程?这对我不起作用。
    • A SwingWorker 采用工作者设计模式(在 wiki 页面中描述)以防止 GUI 在您有多个任务时冻结。 GUI 的更新仍然是从 GUI 线程完成的,因为 SwingWorker 在其操作完成时会回调。根据您的评论,这似乎不适合您。如果您的操作需要在单个线程上完成,则使用具有单个消费者(线程)和多个生产者的生产者-消费者模式 - 仅让消费者执行任务。
    • @Chap,还有一件事:您是要阻止单个任务被多个线程执行,还是要阻止多个任务同时执行(在多个线程上)?我之前的评论可能是错误的,具体取决于您所说的“我需要通过单个线程串行处理每个任务。”
    • 我正在尝试强制单个方法(“getRecordAndBufferNext”)在单个线程上运行 - 这样,如果在第一个方法完成之前发生对该方法的另一个请求,它将排队落后于第一个,而不是被发送到另一个线程并与第一个竞争。我不知道这是否回答了你的问题......?我知道我必须摆脱 GUI 线程的工作;我只想确保工作请求(“从数据集中获取下一条记录”)一个接一个地执行,而不是同时执行。
    • @Chap,这回答了我的问题,所以我以前的 cmets 没有任何变化:只需使用单个消费者和多个生产者(如果您甚至需要生产者)。
    猜你喜欢
    • 2011-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多