import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class ReadersWritersProblem { // Shared data by readers and writers private static int sharedData = 0; // Lock for reader-writer access private static final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); private static final Lock readLock = readWriteLock.readLock(); private static final Lock writeLock = readWriteLock.writeLock(); static class Reader implements Runnable { @Override public void run() { for (int i = 0; i < 5; i++) { readLock.lock(); try { System.out.println(Thread.currentThread().getName() + " reads: " + sharedData); Thread.sleep(100); // Simulate read operation } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { readLock.unlock(); } } } } static class Writer implements Runnable { @Override public void run() { for (int i = 0; i < 5; i++) { writeLock.lock(); try { sharedData++; System.out.println(Thread.currentThread().getName() + " writes: " + sharedData); Thread.sleep(100); // Simulate write operation } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { writeLock.unlock(); } } } } public static void main(String[] args) { // Creating reader and writer threads Thread reader1 = new Thread(new Reader(), "Reader 1"); Thread reader2 = new Thread(new Reader(), "Reader 2"); Thread writer1 = new Thread(new Writer(), "Writer 1"); Thread writer2 = new Thread(new Writer(), "Writer 2"); // Start threads reader1.start(); reader2.start(); writer1.start(); writer2.start(); } }