Merge pull request #802 from iluwatar/Issue#699
Resolves #699 Intermittent failure was due to Thread.sleep in the code
This commit is contained in:
commit
f5eaf06c1c
@ -0,0 +1,10 @@
|
|||||||
|
package com.iluwatar.balking;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface to simulate delay while executing some work.
|
||||||
|
*/
|
||||||
|
public interface DelayProvider {
|
||||||
|
void executeAfterDelay(long interval, TimeUnit timeUnit, Runnable task);
|
||||||
|
}
|
@ -25,17 +25,38 @@ package com.iluwatar.balking;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Washing machine class
|
* Washing machine class
|
||||||
*/
|
*/
|
||||||
public class WashingMachine {
|
public class WashingMachine {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(WashingMachine.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(WashingMachine.class);
|
||||||
|
private final DelayProvider delayProvider;
|
||||||
private WashingMachineState washingMachineState;
|
private WashingMachineState washingMachineState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of WashingMachine
|
||||||
|
*/
|
||||||
public WashingMachine() {
|
public WashingMachine() {
|
||||||
washingMachineState = WashingMachineState.ENABLED;
|
this((interval, timeUnit, task) -> {
|
||||||
|
try {
|
||||||
|
Thread.sleep(timeUnit.toMillis(interval));
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
ie.printStackTrace();
|
||||||
|
}
|
||||||
|
task.run();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of WashingMachine using provided delayProvider. This constructor is used only for
|
||||||
|
* unit testing purposes.
|
||||||
|
*/
|
||||||
|
public WashingMachine(DelayProvider delayProvider) {
|
||||||
|
this.delayProvider = delayProvider;
|
||||||
|
this.washingMachineState = WashingMachineState.ENABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WashingMachineState getWashingMachineState() {
|
public WashingMachineState getWashingMachineState() {
|
||||||
@ -56,12 +77,8 @@ public class WashingMachine {
|
|||||||
washingMachineState = WashingMachineState.WASHING;
|
washingMachineState = WashingMachineState.WASHING;
|
||||||
}
|
}
|
||||||
LOGGER.info("{}: Doing the washing", Thread.currentThread().getName());
|
LOGGER.info("{}: Doing the washing", Thread.currentThread().getName());
|
||||||
try {
|
|
||||||
Thread.sleep(50);
|
this.delayProvider.executeAfterDelay(50, TimeUnit.MILLISECONDS, this::endOfWashing);
|
||||||
} catch (InterruptedException ie) {
|
|
||||||
ie.printStackTrace();
|
|
||||||
}
|
|
||||||
endOfWashing();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,11 +22,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.iluwatar.balking;
|
package com.iluwatar.balking;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
@ -36,32 +33,39 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||||||
*/
|
*/
|
||||||
public class WashingMachineTest {
|
public class WashingMachineTest {
|
||||||
|
|
||||||
private volatile WashingMachineState machineStateGlobal;
|
private FakeDelayProvider fakeDelayProvider = new FakeDelayProvider();
|
||||||
|
|
||||||
@Disabled
|
|
||||||
@Test
|
@Test
|
||||||
public void wash() throws Exception {
|
public void wash() {
|
||||||
WashingMachine washingMachine = new WashingMachine();
|
WashingMachine washingMachine = new WashingMachine(fakeDelayProvider);
|
||||||
ExecutorService executorService = Executors.newFixedThreadPool(2);
|
|
||||||
executorService.execute(washingMachine::wash);
|
|
||||||
executorService.execute(() -> {
|
|
||||||
washingMachine.wash();
|
washingMachine.wash();
|
||||||
machineStateGlobal = washingMachine.getWashingMachineState();
|
washingMachine.wash();
|
||||||
});
|
|
||||||
executorService.shutdown();
|
WashingMachineState machineStateGlobal = washingMachine.getWashingMachineState();
|
||||||
try {
|
|
||||||
executorService.awaitTermination(10, TimeUnit.SECONDS);
|
fakeDelayProvider.task.run();
|
||||||
} catch (InterruptedException ie) {
|
|
||||||
ie.printStackTrace();
|
// washing machine remains in washing state
|
||||||
}
|
|
||||||
assertEquals(WashingMachineState.WASHING, machineStateGlobal);
|
assertEquals(WashingMachineState.WASHING, machineStateGlobal);
|
||||||
|
|
||||||
|
// washing machine goes back to enabled state
|
||||||
|
assertEquals(WashingMachineState.ENABLED, washingMachine.getWashingMachineState());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void endOfWashing() throws Exception {
|
public void endOfWashing() {
|
||||||
WashingMachine washingMachine = new WashingMachine();
|
WashingMachine washingMachine = new WashingMachine();
|
||||||
washingMachine.wash();
|
washingMachine.wash();
|
||||||
assertEquals(WashingMachineState.ENABLED, washingMachine.getWashingMachineState());
|
assertEquals(WashingMachineState.ENABLED, washingMachine.getWashingMachineState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class FakeDelayProvider implements DelayProvider {
|
||||||
|
private Runnable task;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void executeAfterDelay(long interval, TimeUnit timeUnit, Runnable task) {
|
||||||
|
this.task = task;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user