【问题标题】:Java reader writerJava 读写器
【发布时间】:2017-04-11 14:28:16
【问题描述】:

我对我在编程语言概念课中学习的一个新概念感到有些困惑。任何信息都会很棒。读写器问题如下:

这个经典问题需要进程同步进行读写。因此,在定义和创建读写线程之前需要一个同步控制器。下面是一个控制器类(有两个方法留给你实现)。为了保持编程的简单性,当你编写读写线程类时(比如三个读者和一个写者),你只需要在开始读或写时象征性地打印一条消息,在读或写结束时再打印一条消息(因此无需创建每个线程读取或写入的实际共享内容)。

这就是我所拥有的。我认为我缺少线程的基本内容。请注意,控制器类和方法是给定的并且是必需的,除了 startWriting() 和 stopWriting() 必须由我实现。谢谢。

class Controller {
private int activeReaders = 0;  
private boolean writerPresent = false;  

protected boolean writeCondition() {
    return activeReaders == 0 && !writerPresent;
}

protected boolean readCondition() {
    return !writerPresent;
}

protected synchronized void startRead() {
    while (!readCondition())
        try { wait(); } catch (InterruptedException ex) {}
    ++activeReaders;
}

protected synchronized void stopRead()  { 
    --activeReaders;
    notifyAll();
}

protected synchronized void startWriting(){
    writerPresent = true;
    System.out.println("Writing has begun");
}

protected synchronized void stopWriting(){
    System.out.println("Reading is now available");
    writerPresent = false;      
}

public static void main(String [] args){
    Controller c = new Controller();

    Thread tRead1   = new Thread(new Runnable() {
        @Override
        public void run(){
            c.startRead();
            System.out.println("Reader 1 has started reading");
            c.stopRead();
            System.out.println("Reader 1 has stopped reading");
        }
    });
    Thread tRead2   = new Thread(new Runnable() {
        @Override
        public void run(){
            c.startRead();
            System.out.println("Reader 2 has started reading");
            c.stopRead();
            System.out.println("Reader 2 has stopped reading");
        }
    });
    Thread tRead3   = new Thread(new Runnable() {
        @Override
        public void run(){
            c.startRead();
            System.out.println("Reader 3 has started reading");
            c.stopRead();
            System.out.println("Reader 3 has stopped reading");
        }
    });
    Thread tWrite1  = new Thread(new Runnable() {
        @Override
        public void run(){
            c.startWriting();
            c.stopWriting();

        }
    });

    tRead1.start();
    tRead2.start();
    tWrite1.start();
    try {
        tWrite1.join();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    tRead3.start();

}

}

【问题讨论】:

  • 到底是什么问题?
  • 请澄清您的具体问题或添加其他详细信息以准确突出您的需要。正如目前所写的那样,很难准确地说出你在问什么。
  • Re,“我认为我缺少一些基本的东西......”你为什么这么认为?你的程序做了什么你没想到的?此外,如果您能突出显示示例的哪些部分是您编写的,以及在作业中提供给您的部分,将会很有帮助。
  • 我的问题是,当使用控制器时,正在读取的线程应该在写入发生时停止,然后在写入结束后继续。这不会像我写的那样发生。就基本问题而言,这是逐字提供给我的信息。
  • startWriting() 之后的所有内容,包括 startWriting() 都是我写的。

标签: java multithreading synchronization


【解决方案1】:

首先,我建议您访问 javadocs 并阅读 wait、notify 和 notifyall 的方法定义。这是Java中基本的等待/锁定/通知系统。

在读者和作者方面,读者应该都在阅读作者,如果没有可用内容,则在作者上使用wait暂停。如果你有多个作者,你可以对等待消息队列的读者做同样的事情。当写入器写入并有更多数据可供读取器使用时,它应该在自己(写入器)上调用notify 以唤醒一个使用者以获取新数据。

让您了解何时可以/应该使用 notifyAll:

Thread.join 通过在正在加入的线程上调用 wait 来工作。线程死亡后,Thread 调用notifyAll 唤醒所有等待它完成的线程。

【讨论】:

  • 他的实际问题是ReadWriteLock 的实现看起来像,而不是PipeChannel。但是,您的答案更适合 Pipe。
  • @ControlAltDel 谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-04
  • 2021-04-15
  • 2014-07-24
  • 1970-01-01
  • 2016-01-03
相关资源
最近更新 更多