implements the #75 reader writer lock, fix the problem of review

This commit is contained in:
hoswey
2016-01-10 21:23:52 +08:00
parent 2f84369003
commit 77d45c35e0
13 changed files with 482 additions and 206 deletions
@@ -2,12 +2,8 @@ package com.iluwatar.reader.writer.lock;
import org.junit.Test;
import com.iluwatar.reader.writer.lock.App;
/**
*
* Application test
*
*/
public class AppTest {
@@ -0,0 +1,84 @@
package com.iluwatar.reader.writer.lock;
import static org.mockito.Mockito.after;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* @author hongshuwei@gmail.com
*/
public class ReaderAndWriterTest {
ExecutorService executeService;
@Before
public void setup() {
executeService = Executors.newFixedThreadPool(2);
}
/**
* Verify reader and writer can only get the lock to read and write orderly
*/
@Test
public void testReadAndWrite() throws Exception {
ReaderWriterLock lock = new ReaderWriterLock();
Reader reader1 = spy(new Reader("Reader 1", lock.readLock()));
Writer writer1 = spy(new Writer("Writer 1", lock.writeLock()));
executeService.submit(reader1);
// Let reader1 execute first
Thread.sleep(50);
executeService.submit(writer1);
verify(reader1, timeout(99).atLeastOnce()).read();
verify(writer1, after(10).never()).write();
verify(writer1, timeout(100).atLeastOnce()).write();
}
/**
* Verify reader and writer can only get the lock to read and write orderly
*/
@Test
public void testWriteAndRead() throws Exception {
ExecutorService executeService = Executors.newFixedThreadPool(2);
ReaderWriterLock lock = new ReaderWriterLock();
Reader reader1 = spy(new Reader("Reader 1", lock.readLock()));
Writer writer1 = spy(new Writer("Writer 1", lock.writeLock()));
executeService.submit(writer1);
// Let reader1 execute first
Thread.sleep(50);
executeService.submit(reader1);
verify(writer1, timeout(99).atLeastOnce()).write();
verify(reader1, after(10).never()).read();
verify(reader1, timeout(100).atLeastOnce()).read();
}
@After
public void tearDown() {
executeService.shutdown();
try {
executeService.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
System.out.println("Error waiting for ExecutorService shutdown");
}
}
}
@@ -0,0 +1,45 @@
package com.iluwatar.reader.writer.lock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
/**
* @author hongshuwei@gmail.com
*/
public class ReaderTest {
/**
* Verify that multiple readers can get the read lock concurrently
*/
@Test
public void testRead() throws Exception {
ExecutorService executeService = Executors.newFixedThreadPool(2);
ReaderWriterLock lock = new ReaderWriterLock();
Reader reader1 = spy(new Reader("Reader 1", lock.readLock()));
Reader reader2 = spy(new Reader("Reader 2", lock.readLock()));
executeService.submit(reader1);
executeService.submit(reader2);
// Read operation will hold the read lock 100 milliseconds, so here we guarantee that each
// readers can read in 99 milliseconds to prove that multiple read can perform in the same time.
verify(reader1, timeout(99).atLeastOnce()).read();
verify(reader2, timeout(99).atLeastOnce()).read();
executeService.shutdown();
try {
executeService.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
System.out.println("Error waiting for ExecutorService shutdown");
}
}
}
@@ -0,0 +1,52 @@
package com.iluwatar.reader.writer.lock;
import static org.mockito.Mockito.after;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
/**
* @author hongshuwei@gmail.com
*/
public class WriterTest {
/**
* Verify that multiple writers will get the lock in order.
*/
@Test
public void testWrite() throws Exception {
ExecutorService executeService = Executors.newFixedThreadPool(2);
ReaderWriterLock lock = new ReaderWriterLock();
Writer writer1 = spy(new Writer("Writer 1", lock.writeLock()));
Writer writer2 = spy(new Writer("Writer 2", lock.writeLock()));
executeService.submit(writer1);
// Let write1 execute first
Thread.sleep(50);
executeService.submit(writer2);
// Write operation will hold the write lock 100 milliseconds, so here we verify that when two
// write excute concurrently
// 1. The first write will get the lock and and write in 60ms
// 2. The second writer will cannot get the lock when first writer get the lock
// 3. The second writer will get the lock as last
verify(writer1, timeout(10).atLeastOnce()).write();
verify(writer2, after(10).never()).write();
verify(writer2, timeout(100).atLeastOnce()).write();
executeService.shutdown();
try {
executeService.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
System.out.println("Error waiting for ExecutorService shutdown");
}
}
}