在Object中执行优先级方法

时间:2014-07-22 10:09:40

标签: java multithreading thread-synchronization

在我的应用程序中,我有一个名为'manager'的对象。我的主线程正在不断调用

     manager.sendData(..);

我还希望从我的主线程中生成一个线程,我会定期向服务器发出请求,并且在我想要调用的任何响应时

     manager.addQueue(..);

具有最高优先级。

但是这会引起问题(manager.addQueue()根本没有被调用),因为manager.sendData(..)正在不断执行(它在无限循环中被调用)。如果有的话是建议的溶液

3 个答案:

答案 0 :(得分:0)

无限循环是多线程中发明的最糟糕的东西,除非你在循环中使用wait()notify() - 或至少sleep()

你应该看看这个:A simple scenario using wait() and notify() in java

答案 1 :(得分:0)

引用Bloch的Effective Java,第二版中第68和69项的前几行:

  

项目68:首选执行程序和任务到线程

     

本书的第一版包含简单工作队列的代码   [Bloch01,第49项]。此类允许客户端将工作项排入队列   用于后台线程的异步处理。什么时候工作   不再需要队列,客户端可以调用一个方法来询问   后台线程在完成后优雅地终止自身   任何已经在队列中的工作。实施很少   不仅仅是一个玩具,但即便如此,它还需要整整一页的细微之处,   精致的代码,易于安全和生动   失败,如果你没有得到正确的。幸运的是,没有理由   再写这种代码了。

     

在1.5版中,java.util.concurrent被添加到Java平台。   这个包包含一个Executor Framework,它是一个灵活的   基于接口的任务执行工具。创建一个工作队列   在各方面都比本书第一版更好   只需要一行代码:...

在下一个项目中,

  

项目69:首选并发实用程序等待并通知

     

本书的第一版专门用一个项目来正确使用   等待并通知(Bloch01,第50项)。它的建议仍然有效   总结在这个项目的末尾,但这个建议远没那么重要   比以前一样。这是因为使用等待的理由要少得多   并通知。从1.5版开始,Java平台提供更高级别   并发实用程序可以执行您以前必须执行的各种操作   手动代码等待并通知。鉴于使用等待的困难   正确通知,您应该使用更高级别的并发   实用工具。

     

java.util.concurrent中的高级实用程序分为三个   类别:执行者框架,仅在其中简要介绍   项目68;并发集合;和同步器。同时   本项目简要介绍了集合和同步器。

听起来像Java的并发教程可能会有所帮助:http://docs.oracle.com/javase/tutorial/essential/concurrency/

答案 2 :(得分:0)

优先处理有一些常见的模式。

使用线程优先级

如果你只有两个线程,并且你自己产生了线程,那么你可以设置它们的优先级。

Thread t = new Thread(yourRunnable);
t.setPriority(Thread.MAX_PRIORITY);
// or MIN_PRIORITY
// or something in between

使用基于优先级的ExecutorService

您可以将对manager的所有来电重构为RunnableCallable个实例。 然后,使用您自己的PriorityQueue和Comparator,可以轻松地将您的工作单元分配给线程池。 请参阅:How do I implement task prioritization using an ExecutorService in Java 5? 如果你真的需要一个强大的优先级,这是我推荐的解决方案,因为conccurent包是当前标准,“go-to”,并发解决方案,并且可以根据需要扩展到尽可能多的线程和优先级。

替代选项包括:

使用多个ExecutorServices

您可以使用两个ExecutorService实例,一个包含2个线程,另一个包含1个,这个想法是允许更多线程处理您最重要的工作,而更少线程处理不太重要的工作。 这是一个解决方法,而不是一个解决方案,但它很容易,并且(几乎)保证您的高优先级任务不会使低优先级的任务挨饿。

使用锁定

这是解决问题的一种更容易出错的方式。但您可以想象锁定对您的经理实例的访问权限,以便在addQueue事件发生时,对sendData的调用将被锁定,直到第一个事件停止。 但这实际上不是优先实施,而是更多的“互斥”模式。

使用生产者/消费者模式

您可以拥有将工作单元创建为一个(或多个)队列的生产者线程。消费者线程然后弹出这个(这些)队列并处理它(调用管理器)。 如果您的队列是PriorityQueue,或者如果您有“高优先级”和“低优先级”事件队列,那么您的消费者可以根据您的需要选择如何处理优先级。

在任何情况下,您都应该确保正确理解分支。

  1. 优先级意味着饥饿的风险是真实的。你应该 相应地平衡您的需求,以防止高度优先饥饿 低优先级
  2. 您是否真的在寻找线程优先级处理,或者 可以替代模式,如互斥或 生产者/消费者解决问题?