在我的应用程序中,我有一个名为'manager'的对象。我的主线程正在不断调用
manager.sendData(..);
我还希望从我的主线程中生成一个线程,我会定期向服务器发出请求,并且在我想要调用的任何响应时
manager.addQueue(..);
具有最高优先级。
但是这会引起问题(manager.addQueue()根本没有被调用),因为manager.sendData(..)正在不断执行(它在无限循环中被调用)。如果有的话是建议的溶液
答案 0 :(得分:0)
无限循环是多线程中发明的最糟糕的东西,除非你在循环中使用wait()
和notify()
- 或至少sleep()
!
答案 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
您可以将对manager
的所有来电重构为Runnable
或Callable
个实例。
然后,使用您自己的PriorityQueue和Comparator,可以轻松地将您的工作单元分配给线程池。
请参阅:How do I implement task prioritization using an ExecutorService in Java 5?
如果你真的需要一个强大的优先级,这是我推荐的解决方案,因为conccurent包是当前标准,“go-to”,并发解决方案,并且可以根据需要扩展到尽可能多的线程和优先级。
替代选项包括:
您可以使用两个ExecutorService实例,一个包含2个线程,另一个包含1个,这个想法是允许更多线程处理您最重要的工作,而更少线程处理不太重要的工作。 这是一个解决方法,而不是一个解决方案,但它很容易,并且(几乎)保证您的高优先级任务不会使低优先级的任务挨饿。
这是解决问题的一种更容易出错的方式。但您可以想象锁定对您的经理实例的访问权限,以便在addQueue
事件发生时,对sendData
的调用将被锁定,直到第一个事件停止。
但这实际上不是优先实施,而是更多的“互斥”模式。
您可以拥有将工作单元创建为一个(或多个)队列的生产者线程。消费者线程然后弹出这个(这些)队列并处理它(调用管理器)。 如果您的队列是PriorityQueue,或者如果您有“高优先级”和“低优先级”事件队列,那么您的消费者可以根据您的需要选择如何处理优先级。
在任何情况下,您都应该确保正确理解分支。