我在java中编程,我有一个List<LogEntry> log
,它在不同的线程之间共享。
这些&#34;作家&#34;线程已在它们之间同步,因此每次只有一个线程可以添加或删除log
然而,由于我试图实现的分布式算法,有一部分日志是&#34;安全&#34;,这意味着它们既不能被作者修改也不能被修改读者(我在下面介绍)。 log
的这一部分由字段int committedIndex
表示,它被初始化为0并且单调增加。
总之,作者修改log
范围内(commitIndex,log.size())
中的元素,而有一个读者可以获取范围log
中包含的[0,commitIndex]
中的元素。读者开始从第一个条目读取,然后读取下一个条目直到他到达log.get(commitIndex)
,然后它停止并进入睡眠状态,直到commitIndex
增加。它会更新一个字段lastApplied
,该字段初始化为0并单调增加,以便记住他在睡觉前读取的最后一个logEntry
。
正如您所看到的,不需要同步读者和作者,因为他们访问log
的不同部分。
我的问题是:我怎样才能醒来&#34; commitIndex
增加时读者的线程?我需要这样的东西(由作家执行):
if(commitIndex is updated)
{
//wake up reader
}
读者:
public void run() {
while(true){
//go to sleeep...
//now the reader is awaken!
while(lastApplied<commitIndex){
//do something with log.get(lastApplied)
lastApplied++;
}
}
显然,为了让你尽可能地理解我想要的东西,我非常简化了我的代码,如果不够清楚我会很抱歉(并且不要犹豫问我什么关于它)。谢谢!
答案 0 :(得分:0)
试试这个:
if(commitIndex is updated)
{
//wake up reader
synchronized(reader)
{
reader.notify();
}
}
答案 1 :(得分:0)
使用共享的LinkedBlockingQueue<Integer>
(在读者和所有作者中)让每位作者向读者发出commitIndex
变量已被修改的信号:
<强>者:强>
if (commitIndex is updated) {
// wake up reader
this.queue.add(commitIndex);
}
<强>阅读器:强>
public void run() {
while (true) {
// take() puts this thread to sleep until a writer calls add()
int commitIndex = this.queue.take();
// now the reader is awaken!
while (lastApplied < commitIndex) {
// do something with log.get(lastApplied)
lastApplied++;
}
}
}
我在这里使用了属性queue
,它应该对应于读者和所有作者的LinkedBlockingQueue
的相同实例。
注意:作为练习留下的异常处理。