### Question:
Writer implements Runnable { public void write() throws InterruptedException { LOGGER.info("{} begin", name); Thread.sleep(writingTime); LOGGER.info("{} finished after writing {}ms", name, writingTime); } Writer(String name, Lock writeLock);  Writer(String name, Lock writeLock, long writingTime); @Override void run(); void write();  }### Answer:
@Test public void testWrite() throws Exception { var executeService = Executors.newFixedThreadPool(2); var lock = new ReaderWriterLock(); var writer1 = spy(new Writer("Writer 1", lock.writeLock())); var writer2 = spy(new Writer("Writer 2", lock.writeLock())); executeService.submit(writer1); Thread.sleep(150); executeService.submit(writer2); executeService.shutdown(); try { executeService.awaitTermination(10, TimeUnit.SECONDS); } catch (InterruptedException e) { LOGGER.error("Error waiting for ExecutorService shutdown", e); } assertTrue(appender.logContains("Writer 1 begin")); assertTrue(appender.logContains("Writer 1 finish")); assertTrue(appender.logContains("Writer 2 begin")); assertTrue(appender.logContains("Writer 2 finish")); }
@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); Thread.sleep(150); executeService.submit(writer2); executeService.shutdown(); try { executeService.awaitTermination(10, TimeUnit.SECONDS); } catch (InterruptedException e) { LOGGER.error("Error waiting for ExecutorService shutdown", e); } assertTrue(appender.logContains("Writer 1 begin")); assertTrue(appender.logContains("Writer 1 finish")); assertTrue(appender.logContains("Writer 2 begin")); assertTrue(appender.logContains("Writer 2 finish")); }