java:如何解决读写器问题?

qnzebej0  于 2021-06-26  发布在  Java
关注(0)|答案(2)|浏览(347)

我想为读者和作者的问题实现一个解决方案。主要规则是,一次只有一个作者可以写,没有其他作者或读者可以写或读,但如果一个作者不写,多个读者可以读。在主类中,我尝试使用 executorService.execute 但我想我有一些问题。我不太了解 executorService . 这个程序永远不会结束,我想有一些输出问题。
我的代码如下:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class ReaderWriter {
public static void main(String [] args) {
    ExecutorService executorService = Executors.newCachedThreadPool();
    ReadWriteLock RW = new ReadWriteLock();

    executorService.execute(new Writer(RW));
    executorService.execute(new Writer(RW));
    executorService.execute(new Writer(RW));
    executorService.execute(new Writer(RW));

    executorService.execute(new Reader(RW));
    executorService.execute(new Reader(RW));
    executorService.execute(new Reader(RW));
    executorService.execute(new Reader(RW));
 }
}

class ReadWriteLock{
    static Semaphore readLock = new Semaphore(1);
    static Semaphore writeLock = new Semaphore(1);
    volatile static int readCount = 0;

    public void readLock() throws InterruptedException {

        readLock.acquire();
        readCount++;
        if (readCount == 1) {
            writeLock.acquire();
        }
        readLock.release();

        //Reading section
        System.out.println("Thread "+Thread.currentThread().getName() + " is READING");
        Thread.sleep(1500);
        System.out.println("Thread "+Thread.currentThread().getName() + " has FINISHED READING");

        //Releasing section
        readLock.acquire();
        readCount--;
        if(readCount == 0) {
            writeLock.release();
        }
        readLock.release();
    }
    public void writeLock() throws InterruptedException {
        writeLock.acquire();
        System.out.println("Thread "+Thread.currentThread().getName() + " is WRITING");
        Thread.sleep(2500);
        writeLock.release();
        System.out.println("Thread "+Thread.currentThread().getName() + " has finished WRITING");
    }
}

class Writer implements Runnable
{
    private ReadWriteLock RW_lock;

    public Writer(ReadWriteLock rw) {
        RW_lock = rw;
    }

    public void run() {
        while (true){
            try {
                RW_lock.writeLock();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Reader implements Runnable
{
    private ReadWriteLock RW_lock;

    public Reader(ReadWriteLock rw) {
        RW_lock = rw;
    }
    public void run() {
        while (true){
            try {
                RW_lock.readLock();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

输出不正确,我认为对于这个问题:

Thread pool-1-thread-1 is WRITING
Thread pool-1-thread-2 is WRITING
Thread pool-1-thread-1 has finished WRITING
Thread pool-1-thread-2 has finished WRITING
Thread pool-1-thread-3 is WRITING
Thread pool-1-thread-3 has finished WRITING
Thread pool-1-thread-4 is WRITING
Thread pool-1-thread-4 has finished WRITING
Thread pool-1-thread-5 is READING
Thread pool-1-thread-8 is READING
Thread pool-1-thread-7 is READING
Thread pool-1-thread-6 is READING
Thread pool-1-thread-8 has FINISHED READING
Thread pool-1-thread-5 has FINISHED READING
Thread pool-1-thread-8 is READING
Thread pool-1-thread-5 is READING
Thread pool-1-thread-6 has FINISHED READING
Thread pool-1-thread-6 is READING
Thread pool-1-thread-7 has FINISHED READING
Thread pool-1-thread-7 is READING
Thread pool-1-thread-5 has FINISHED READING
Thread pool-1-thread-5 is READING
Thread pool-1-thread-8 has FINISHED READING

在这个输出中,有两个写入程序同时写入。

rdlzhqv9

rdlzhqv91#

您需要在main方法中调用executorservice的shutdown或shutdownandawaittermination方法。

uhry853o

uhry853o2#

这个程序永远不会结束,我想有一些输出问题。
将标志添加到 ReadWriteLock 类,该类向线程发出停止工作的信号:

private final AtomicBoolean keep_working = new AtomicBoolean(true);

ReadWriteLock 类发出停止线程的信号:

public void stopThreads(){
    keep_working.set(false);
}

以及查询标志的方法:

public boolean keepWorking(){
    return keep_working.get();
}

更改 Writer 以及
Reader run 方法:

public void run() {
        while (RW_lock.keepWorking()){
           ...
        }
    }

在main类上添加对方法的调用 ExecutorService.awaitTermination() , ReadWriteLock.stopThreads ,和 ExecutorService.shutdown() :

public static void main(String [] args) {
    ExecutorService executorService = Executors.newCachedThreadPool();
    ReadWriteLock RW = new ReadWriteLock();

    executorService.execute(new Writer(RW));
    executorService.execute(new Writer(RW));
    executorService.execute(new Writer(RW));
    executorService.execute(new Writer(RW));

    executorService.execute(new Reader(RW));
    executorService.execute(new Reader(RW));
    executorService.execute(new Reader(RW));
    executorService.execute(new Reader(RW));
    try {
        executorService.awaitTermination(5, TimeUnit.SECONDS);
    } catch (InterruptedException e) { // ...} 
    RW.stopThreads();
    executorService.shutdown();
}

现在还有其他问题:
主要规则是,一次只有一个作者可以写,没有其他作者或读者可以写或读,但如果一个作者不写,多个读者可以读。
那么你应该申报 Semaphore 对于具有多个许可证的读锁(即。, static Semaphore readLock = new Semaphore(1); ):
输出问题:
输出不正确,我认为对于这个问题:
但在我的输出中,两个作者同时在写作。
这是因为:

public void writeLock() throws InterruptedException {
    writeLock.acquire();
    System.out.println("Thread "+Thread.currentThread().getName() + " is WRITING");
    Thread.sleep(2500);
    writeLock.release();
    System.out.println("Thread "+Thread.currentThread().getName() + " has finished WRITING");
}

在打印“已完成写入”之前释放锁,因此,等待释放该锁的线程进入并打印“正在写入”,而第一个线程还没有时间打印“已完成写入”。所以您需要将代码更改为:

public void writeLock() throws InterruptedException {
        writeLock.acquire();
        System.out.println("Thread "+Thread.currentThread().getName() + " is WRITING");
        Thread.sleep(2500);
        System.out.println("Thread "+Thread.currentThread().getName() + " has finished WRITING");
        writeLock.release();
    }

相关问题