Java:如何解决读写器问题?
我想为读者和作者的问题实现一个解决方案。主要规则是,一次只能写一个作者,没有其他作者或读者可以写或读,但如果一个作者不写,多个读者可以读。在main类中,我尝试使用Java:如何解决读写器问题?,java,multithreading,concurrency,parallel-processing,synchronization,Java,Multithreading,Concurrency,Parallel Processing,Synchronization,我想为读者和作者的问题实现一个解决方案。主要规则是,一次只能写一个作者,没有其他作者或读者可以写或读,但如果一个作者不写,多个读者可以读。在main类中,我尝试使用executorService.execute运行线程,但我想我遇到了一些问题。我对执行器服务知之甚少。程序永远不会结束,我想可能会有一些输出问题 我的代码如下: import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; im
executorService.execute运行线程,但我想我遇到了一些问题。我对执行器服务知之甚少。程序永远不会结束,我想可能会有一些输出问题
我的代码如下:
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
在该输出中,有两个写入程序同时写入
输出编辑:
Thread pool-1-thread-1 is WRITING
Thread pool-1-thread-1 has finished WRITING
Thread pool-1-thread-1 is WRITING
Thread pool-1-thread-1 has finished WRITING
Thread pool-1-thread-4 is WRITING
Thread pool-1-thread-4 has finished WRITING
Thread pool-1-thread-3 is WRITING
Thread pool-1-thread-3 has finished WRITING
Thread pool-1-thread-2 is WRITING
Thread pool-1-thread-2 has finished WRITING
Thread pool-1-thread-8 is READING
Thread pool-1-thread-7 is READING
Thread pool-1-thread-5 is READING
Thread pool-1-thread-6 is READING
Thread pool-1-thread-8 has FINISHED READING
Thread pool-1-thread-7 has FINISHED READING
Thread pool-1-thread-5 has FINISHED READING
Thread pool-1-thread-6 has FINISHED READING
您需要在主方法中调用ExecutorService的shutdown或ShutdownAndWaitTermination方法。您需要在主方法中调用ExecutorService的shutdown或ShutdownAndWaitTermination方法
程序永远不会结束,我想可能会有一些输出问题
在ReadWriteLock
类中添加一个标志,以向线程发出停止工作的信号:
private final AtomicBoolean keep_working = new AtomicBoolean(true);
在ReadWriteLock
类中添加一个方法来通知线程停止:
public void stopThreads(){
keep_working.set(false);
}
并添加查询标志的方法:
相应地调整编写器
和读取器
运行
方法:
public void run() {
while (RW_lock.keepWorking()){
...
}
}
在主类上,添加对方法ExecutorService.awaitTermination()
、ReadWriteLock.stopThreads
和ExecutorService.shutdown()的调用:
输出不正确,我认为对于这个问题:
(...)
在该输出中,有两个写入程序同时写入
这是因为:
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();
}
主要规则是,一次只能写一个作家,其他作家不能
作者或读者可以写或读,但如果作者不写,
多个阅读器可以阅读
实际上,您可以利用Java接口
读写锁维护一对关联锁,一个用于
只读操作和一个用于写入的操作。可以保持读取锁
由多个读卡器线程同时执行,只要没有
写入程序。写入锁是独占的。所有读写锁
实现必须保证内存同步效果
写锁操作的类型(如锁接口中指定的)也保持不变
关于关联的读锁。就是一根线
成功获取读取锁将看到在
写锁的以前版本
读写锁允许在内存中实现更高级别的并发
访问互斥锁允许之外的共享数据。
它利用了这样一个事实,即虽然一次只有一个线程(一个
编写器线程)可以修改共享数据,在许多情况下,可以修改任意数量的
线程可以同时读取数据(因此读线程)。在里面
理论上,通过使用
读写锁定将比使用
互斥锁。实际上,这种并发性的增加将
只有在多处理器上完全实现,并且
共享数据的访问模式是合适的
通过使用该接口,您可以将readLock
和writeLock
方法大大简化为以下内容:
public void readLock() throws InterruptedException {
shared_resource.readLock().lock();
System.out.println("Thread "+Thread.currentThread().getName() + " is READING");
Thread.sleep(1500);
System.out.println("Thread "+Thread.currentThread().getName() + " has FINISHED READING");
shared_resource.readLock().unlock();
}
public void writeLock() throws InterruptedException {
shared_resource.writeLock().lock();
System.out.println("Thread "+Thread.currentThread().getName() + " is WRITING");
Thread.sleep(2500);
System.out.println("Thread "+Thread.currentThread().getName() + " has finished WRITING");
shared_resource.writeLock().unlock();
}
要完成此操作,应添加一个统计写入和读取次数的变量。因此,如果没有写入任何内容,则读取线程应该等待,同时,写入线程应该写入一些内容,依此类推
程序永远不会结束,我想可能会有一些输出问题
在ReadWriteLock
类中添加一个标志,以向线程发出停止工作的信号:
private final AtomicBoolean keep_working = new AtomicBoolean(true);
在ReadWriteLock
类中添加一个方法来通知线程停止:
public void stopThreads(){
keep_working.set(false);
}
并添加查询标志的方法:
相应地调整编写器
和读取器
运行
方法:
public void run() {
while (RW_lock.keepWorking()){
...
}
}
在主类上,添加对方法ExecutorService.awaitTermination()
、ReadWriteLock.stopThreads
和ExecutorService.shutdown()的调用:
输出不正确,我认为对于这个问题:
(...)
在该输出中,有两个写入程序同时写入
这是因为:
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();
}
主要规则是,一次只能写一个作家,其他作家不能
作者或读者可以写或读,但如果作者不写,
多个阅读器可以阅读
实际上,您可以利用Java接口
读写锁维护一对关联锁,一个用于
只读操作和一个用于写入的操作。可以保持读取锁
由多个读卡器线程同时执行,只要没有
写入程序。写入锁是独占的。所有读写锁
实现必须保证内存同步效果
写锁操作的类型(如锁接口中指定的)也保持不变
关于关联的读锁。就是一根线
成功获取读取锁将看到在
写锁的以前版本
读写锁允许在内存中实现更高级别的并发
访问互斥锁允许之外的共享数据。
它利用了这样一个事实,即虽然一次只有一个线程(一个
编写器线程)可以修改共享数据,在许多情况下,可以修改任意数量的
线程可以同时读取数据(因此读卡器t