java多个编写器一个读取器而不并发
我正在用java编程,我有一个List<LogEntry> log
,它在不同的线程之间共享
这些“编写器”线程已经在它们之间同步,因此每次只有一个线程可以添加或删除log
然而,由于我试图实现的分布式算法,日志中有一部分是“安全的”,这意味着作者或读者都不能修改它们(我将在下面介绍)。这部分log
由字段int committedIndex
表示,该字段初始化为0并单调递增
总之,编写器修改了范围(commitIndex,log.size())
内的log
中的元素,而有一个读取器获取范围[0,commitIndex]
中包含的log
中的元素。读取器从第一个条目开始读取,然后读取下一个条目,直到到达log.get(commitIndex)
,然后它停止并进入睡眠状态,直到commitIndex
增加。它更新一个字段lastApplied
,该字段初始化为0并单调增加,以便记住他在睡觉前读取的最后一个logEntry
如您所见,不需要同步读取器和写入器,因为它们访问log
的不同部分
我的问题是:当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++;
}
}
显然,为了让您尽可能更好地理解我想要的内容,我非常简化了我的代码。如果不够清楚,我很抱歉(请不要犹豫,向我询问任何相关信息)。谢谢
# 1 楼答案
试试这个:
# 2 楼答案
使用共享的^{} (在读卡器和所有写卡器之间)让每个写卡器向读卡器发出
commitIndex
变量已被修改的信号:作者:
阅读器:
这里我使用了属性
queue
,它应该对应于LinkedBlockingQueue
的同一个实例,用于读者和所有作者注意:将异常处理留作练习