许多作家一个读者没有并发

时间:2015-03-04 12:49:12

标签: java multithreading writer reader

我在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++;
        }
    }

显然,为了让你尽可能地理解我想要的东西,我非常简化了我的代码,如果不够清楚我会很抱歉(并且不要犹豫问我什么关于它)。谢谢!

2 个答案:

答案 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的相同实例。

注意:作为练习留下的异常处理。