我相信无论使用何种语言都可以考虑我的问题但是,为了获得一些'锚',我将使用Java语言对其进行描述。
让我们考虑以下场景: 我有一个 PickyHost 类扩展了Thread及其实例, 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
}
}
此外,在后台,我有很多来宾实例正在运行(他们还扩展主题类),偶尔会有一些来宾想要在 pickyHostInst 上使用参数 g 调用输入方法。 现在,我希望 PickyHost 在以下意义上挑剔:
在某人调用输入方法后,会立即将 g 放在来宾列表的末尾,并强制 g 等待通知。另外(我认为这里存在问题的关键)它会自行进行5秒钟的睡眠,并以某种方式允许(在这5秒内)其他客人调用输入方法(如果发生这种情况,那么它会忘记)关于它需要多长时间睡眠并重置其闹钟再睡5秒钟 - 我称之为敏感睡眠。
正如你所看到的,如果很多客人到达, pickyHostInst 睡觉的总时间可能很长 - 例如:A到达,然后4秒后B到达,然后又过了4秒C到达并且等等。然而,假设已经创建了A,B,......,G的链,从G到达的那一刻到5秒之后,没有人到达。 然后我希望 pickyHostInst 调用 pickGuests 方法,该方法使用某种算法确定{A,B,...,G的子集 S客人通知他们可以停止等待并继续他们通常做的事情,而且从来宾列表中删除S的元素。方法 pickGuests 可能需要一些时间才能完成,同时一些客人H可能已到达并调用输入 - 然后输入应正常进行但< strong> pickGuests 应该忽略H并且在它与{A,B,...,G}的最后一次调用处理结束时 - 而不是{A,B,...,G,H}。 完成 pickGuests 之后, pickyHostInst 应该(这里我有2个想法 - 实施其中任何一个都会让我开心:)) 任
最后,经过长时间的介绍,我的问题 - 我需要哪些工具来完成这样的任务?不幸的是,我在各种锁和多线程/锁定机制的丰富性中有点迷失,并且无法辨别哪一个适合我的问题(或哪些,以某种方式结合)。
我将非常感谢一些能让我走上正轨的代码草图。
答案 0 :(得分:1)
您可以使用java.util.Timer
对象,可以使用enter
方法重置该对象。计时器任务将在其自己的线程中运行,如果未事先取消,则为您进行拣选。
请注意,enter
方法将在众多Guest
个线程之一上运行。这意味着它可能应该同步。最简单的方法是将synchronized
关键字添加到Java中的方法声明:public synchronized void enter(Guest g)
。这将确保一次只能有一位客人进入。您可以将计时器取消/重启代码放在此处。
java.util.Timer
通过抽象java.util.TimerTask
类的方式。这是一种Runnable
类型,它还有一种取消任务的方法。我的建议是安排一个任务,当客人进入时,将在5000毫秒间隔后挑选客人。如果前一个guest虚拟机中的任务正在运行,请先取消它。
enter
方法应该获取访客的锁(使用同步块)并让访客等待。选择应该在您选择的访客上调用notify()
方法。这将允许他们继续执行。
从队列中删除选定的guest虚拟机时,请注意默认情况下Java集合不是线程安全的。您必须使用外部锁定以确保在添加和删除guest虚拟机时没有其他人正在修改您的列表。 Collections.synchronizedList(List)
方法提供了一种方便的方法。
以下是讨论我提到的主题的链接列表:
答案 1 :(得分:1)
我可能会这样做。我会尽量避免使用notify
/ notifyAll
,因为虚假的唤醒会让代码混乱,并且会使代码混乱不堪。虽然这个名字有点奇怪,但{IMO}在这里是一个更好的选择。
CountDownLatch