Design a synchronization primitive that coordinates readers and writers around a shared resource.
Implement the ReadersWriters class:
read(readAction) waits until read access is available, then invokes readAction exactly once.write(writeAction) waits until write access is available, then invokes writeAction exactly once.
Any number of readers may execute their callbacks at the same time. A writer must execute alone: its callback cannot overlap another writer or any reader.
Use writer preference to prevent writer starvation. Once at least one writer is waiting, readers that arrive later must wait until the queued writers have had an opportunity to proceed. Readers that were already active may finish normally.
The access granted by a method lasts for the entire callback. The method must not return before its callback finishes, and it must release access after the callback returns.
The judge creates all reader and writer threads. Your class should only coordinate them; it should not create worker threads itself.
The judge preloads the standard concurrency APIs for every supported language. You do not need to add import, include, using, or package statements.
Example 1:
Input:
Output:
Example 2:
Input:
Output:
Explanation: lateRead cannot bypass the waiting writer.
Constraints
- Every callback must be invoked exactly once.
- Reader and writer methods may be called concurrently from many threads.
- Reader callbacks do not modify the protected resource.
- Callbacks supplied by the judge do not throw exceptions.
- The same
ReadersWriters instance is reused for all operations in a test case.