Skip to content

Commit f5eaf06

Browse files
authored
Merge pull request iluwatar#802 from iluwatar/Issue#699
Resolves iluwatar#699 Intermittent failure was due to Thread.sleep in the code
2 parents 3c6fb0c + 829df03 commit f5eaf06

File tree

3 files changed

+59
-28
lines changed

3 files changed

+59
-28
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.iluwatar.balking;
2+
3+
import java.util.concurrent.TimeUnit;
4+
5+
/**
6+
* An interface to simulate delay while executing some work.
7+
*/
8+
public interface DelayProvider {
9+
void executeAfterDelay(long interval, TimeUnit timeUnit, Runnable task);
10+
}

balking/src/main/java/com/iluwatar/balking/WashingMachine.java

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,38 @@
2525
import org.slf4j.Logger;
2626
import org.slf4j.LoggerFactory;
2727

28+
import java.util.concurrent.TimeUnit;
29+
2830
/**
2931
* Washing machine class
3032
*/
3133
public class WashingMachine {
3234

3335
private static final Logger LOGGER = LoggerFactory.getLogger(WashingMachine.class);
34-
36+
private final DelayProvider delayProvider;
3537
private WashingMachineState washingMachineState;
3638

39+
/**
40+
* Creates a new instance of WashingMachine
41+
*/
3742
public WashingMachine() {
38-
washingMachineState = WashingMachineState.ENABLED;
43+
this((interval, timeUnit, task) -> {
44+
try {
45+
Thread.sleep(timeUnit.toMillis(interval));
46+
} catch (InterruptedException ie) {
47+
ie.printStackTrace();
48+
}
49+
task.run();
50+
});
51+
}
52+
53+
/**
54+
* Creates a new instance of WashingMachine using provided delayProvider. This constructor is used only for
55+
* unit testing purposes.
56+
*/
57+
public WashingMachine(DelayProvider delayProvider) {
58+
this.delayProvider = delayProvider;
59+
this.washingMachineState = WashingMachineState.ENABLED;
3960
}
4061

4162
public WashingMachineState getWashingMachineState() {
@@ -56,12 +77,8 @@ public void wash() {
5677
washingMachineState = WashingMachineState.WASHING;
5778
}
5879
LOGGER.info("{}: Doing the washing", Thread.currentThread().getName());
59-
try {
60-
Thread.sleep(50);
61-
} catch (InterruptedException ie) {
62-
ie.printStackTrace();
63-
}
64-
endOfWashing();
80+
81+
this.delayProvider.executeAfterDelay(50, TimeUnit.MILLISECONDS, this::endOfWashing);
6582
}
6683

6784
/**

balking/src/test/java/com/iluwatar/balking/WashingMachineTest.java

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,8 @@
2222
*/
2323
package com.iluwatar.balking;
2424

25-
import org.junit.jupiter.api.Disabled;
2625
import org.junit.jupiter.api.Test;
2726

28-
import java.util.concurrent.ExecutorService;
29-
import java.util.concurrent.Executors;
3027
import java.util.concurrent.TimeUnit;
3128

3229
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -36,32 +33,39 @@
3633
*/
3734
public class WashingMachineTest {
3835

39-
private volatile WashingMachineState machineStateGlobal;
36+
private FakeDelayProvider fakeDelayProvider = new FakeDelayProvider();
4037

41-
@Disabled
4238
@Test
43-
public void wash() throws Exception {
44-
WashingMachine washingMachine = new WashingMachine();
45-
ExecutorService executorService = Executors.newFixedThreadPool(2);
46-
executorService.execute(washingMachine::wash);
47-
executorService.execute(() -> {
48-
washingMachine.wash();
49-
machineStateGlobal = washingMachine.getWashingMachineState();
50-
});
51-
executorService.shutdown();
52-
try {
53-
executorService.awaitTermination(10, TimeUnit.SECONDS);
54-
} catch (InterruptedException ie) {
55-
ie.printStackTrace();
56-
}
39+
public void wash() {
40+
WashingMachine washingMachine = new WashingMachine(fakeDelayProvider);
41+
42+
washingMachine.wash();
43+
washingMachine.wash();
44+
45+
WashingMachineState machineStateGlobal = washingMachine.getWashingMachineState();
46+
47+
fakeDelayProvider.task.run();
48+
49+
// washing machine remains in washing state
5750
assertEquals(WashingMachineState.WASHING, machineStateGlobal);
51+
52+
// washing machine goes back to enabled state
53+
assertEquals(WashingMachineState.ENABLED, washingMachine.getWashingMachineState());
5854
}
5955

6056
@Test
61-
public void endOfWashing() throws Exception {
57+
public void endOfWashing() {
6258
WashingMachine washingMachine = new WashingMachine();
6359
washingMachine.wash();
6460
assertEquals(WashingMachineState.ENABLED, washingMachine.getWashingMachineState());
6561
}
6662

63+
private class FakeDelayProvider implements DelayProvider {
64+
private Runnable task;
65+
66+
@Override
67+
public void executeAfterDelay(long interval, TimeUnit timeUnit, Runnable task) {
68+
this.task = task;
69+
}
70+
}
6771
}

0 commit comments

Comments
 (0)