【发布时间】:2013-12-25 17:19:30
【问题描述】:
我相信无论使用哪种语言都可以考虑我的问题,但是为了有一些“锚”,我将使用 Java 语言来描述它。
让我们考虑以下场景: 我有一个扩展 Thread 的类 PickyHost 和它的一个实例,pickyHostInst 正在运行。 该类可能如下所示:
class PickyHost extends Thread {
private ArrayList<Guest> guests;
public void enter(Guest g) {
// deal with g
}
private void pickGuests() {
// ...
}
public void run() {
// listen indefinitely
}
}
此外,在后台,我有许多 Guest 实例正在运行(它们还扩展了 Thread 类),并且偶尔会有一些 guest > 想要在 pickyHostInst 上调用 enter 方法,参数 g 是它本身。 现在,我希望 PickyHost 在以下意义上是挑剔的:
在有人调用 enter 方法后,它会将 g 放在 guests 列表的末尾并强制 g等待通知。此外(我认为这是问题的症结所在)它会自行休眠 5 秒,并以某种方式允许(在这 5 秒内)其他客人调用 enter 方法(如果发生这种情况,那么它会忘记关于它必须睡眠多长时间并将其闹钟重新设置为恰好再次睡眠 5 秒)- 我将其称为敏感睡眠。
如您所见,如果有很多客人到达,pickyHostInst 的总睡眠时间可能会很长——例如:A 到达,然后 4 秒后 B 到达,然后再过 4 秒 C 到达,然后很快。但是,假设已经创建了一条客人链A,B,...,G,并且从G到达的那一刻到5秒后,没有人到达。 然后我希望 pickyHostInst 调用 pickGuests 方法,该方法使用某种算法确定 {A, B, ..., G 的 subset S } 的客人通知他们可以停止等待并继续做他们通常做的事情,并且从 guests 列表中删除 S 的元素。方法 pickGuests 可能需要一些时间才能完成,同时一些客人 H 可能已经到达并调用了 enter - 然后 enter 应该正常进行但 pickGuests 应该忽略 H 并在其最后一次调用结束时处理 {A, B, ..., G} - 而不是 {A, B, ..., G, H}。 完成 pickGuests 后,pickyHostInst 应该(这里我有 2 个想法 - 实施其中任何一个都会让我开心 :)) 要么
- 再次进入 5 秒的敏感睡眠,之后,如果 H 到达后没有客人,则再次调用 pickGuests,或者
- 像往常一样通过 enter 方法同时为客人提供服务,但仅在之后调用 pickGuests max("S 中的最后一位客人(从最后一次调用开始)通知 pickyHostInst 的时刻(例如:S 中的最后一个“谢谢你,主人先生”)", "在 5 秒后最后(最新)客人调用进入“)。
最后,经过长时间的介绍,我的问题 - 我需要哪些工具来完成这样的任务?不幸的是,我有点迷失在各种锁和多线程/锁定机制的丰富性中,无法辨别哪一个适合我的问题(或者哪些以某种方式组合)。
我将非常感谢一些能让我走上正轨的代码草图。
【问题讨论】:
-
tl;dr 和 all 这个 bold 无处不在 使 难以 制作感觉的。
-
我会尝试只使用睡眠、等待、通知、通知所有。我怀疑在这项任务中我会遇到一些我无法通过使用它们来实现的东西。你有没有遇到什么特别的卡住的地方?
-
@MikeW - 我认为区分生活在程序中的实体可以帮助理解我相当长的信息。可能是错的...
标签: java multithreading wait synchronized notify