繁体   English   中英

读者编写问题并发Java

[英]Readers writers problem concurrent Java

这是读者作者的实现,即许多读者可以阅读但只有一个作家可以在任何时候写。 这是否按预期工作?

public class ReadersWriters extends Thread{

static int num_readers = 0;
static int writing = 0;

public void read_start() throws InterruptedException {         

    synchronized(this.getClass()) {
        while(writing == 1) wait();
        num_readers++;
    }        
}

public void read_end() {
    synchronized(this.getClass()) {
        if(--num_readers == 0) notifyAll();
    }
}

public void write_start() throws InterruptedException{

    synchronized(this.getClass()) {
        while(num_readers > 0) wait();
        writing = 1;
    } 
}

public void write_end() {
    this.getClass().notifyAll();
}
}

此实现也与声明每个方法有任何不同

public static synchronized read_start() 

例如?

谢谢

不 - 你隐式调用this.wait() ,尽管没有在this同步,而是在类上。 同样你打电话this.notifyAll()read_end 我的建议:

  • 不要扩展Thread - 你根本就没有专门的线程。
  • 不要从实例成员中使用这样的静态变量; 它使它看起来像每个对象的状态,但实际上没有。 就个人而言,我只是使用实例变量。
  • 不要在名称中使用下划线 - 传统的Java名称是numReadersreadEnd (或更好, endRead )等。
  • 如果你能提供帮助,请不要同步this或类。 我个人更喜欢有一个private final Object变量来锁定(等待等)。 这样您就知道只有您的代码可以在其上进行同步,这使得更容易推理。
  • 你从不将writing设置为0.首先使用整数而不是boolean任何理由?

当然,如果可能的话,最好在框架中使用这个类 - 但我希望你真的写这个来更好地理解线程。

您可以通过使用更简单的方式实现目标

java.util.concurrent.locks.ReentrantReadWriteLock

当你开始阅读时,只需抓住java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock,当你开始写时,抓住java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock。

这个类正是为了这个目的 - 允许多个与单个writer完全互斥的读者。

您对read_start特定实现并不等同于简单地声明方法已synchronized 正如J. Skeed所指出的那样,您需要对正在synchronize的对象调用notify (和wait )。 您不能使用不相关的对象(此处为:类)。 并且在方法上使用synchronized修改不会使方法隐式调用wait或类似的东西。

BTW是一种读/写锁的实现,它随核心JDK一起提供: java.util.concurrent.locks.ReentrantReadWriteLock 使用该代码,您的代码可能如下所示:

class Resource {
    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    private final Lock rlock = lock.readLock();
    private final Lock wlock = lock.writeLock();

    void read() { ... /* caller has to hold the read lock */ ... }
    void write() { ... /* caller has to hold the write lock */ ... }

    Lock readLock() { return rlock; }
    Lock writeLock() { return wlock; }
}

用法

final Resource r = ...;

r.readLock().lock();
try {
    r.read();
} finally {
    r.unlock();
}

和类似的写操作。

示例代码在this.getClass()上进行同步, ReadersWriters在同一个类加载器中为多个ReadersWriters实例返回相同的Class对象。 如果存在多个ReadersWriters实例,即使您有多个线程,也会争用此共享锁。 这类似于将static关键字添加到私有锁定字段(如Jon Skeet建议的那样),并且可能导致比在this私有锁定对象上同步更差的性能。 更具体地说,正在读取的一个线程将阻塞正在写入的另一个线程,这可能是不合需要的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM