|
10 | 10 | import java.io.FileOutputStream; |
11 | 11 | import java.io.IOException; |
12 | 12 | import java.net.URL; |
| 13 | +import java.util.ArrayList; |
| 14 | +import java.util.List; |
| 15 | +import java.util.concurrent.CompletionService; |
| 16 | +import java.util.concurrent.ExecutorCompletionService; |
13 | 17 | import java.util.concurrent.ExecutorService; |
| 18 | +import java.util.concurrent.Future; |
14 | 19 | import java.util.concurrent.atomic.AtomicBoolean; |
| 20 | +import java.util.concurrent.atomic.AtomicInteger; |
15 | 21 |
|
16 | 22 | import static io.microsphere.io.FileUtils.cleanDirectory; |
17 | 23 | import static io.microsphere.io.FileUtils.deleteDirectory; |
|
27 | 33 | import static io.microsphere.util.StringUtils.EMPTY_STRING; |
28 | 34 | import static io.microsphere.util.SystemUtils.IS_OS_WINDOWS; |
29 | 35 | import static io.microsphere.util.SystemUtils.JAVA_IO_TMPDIR; |
30 | | -import static java.nio.charset.StandardCharsets.UTF_8; |
| 36 | +import static java.lang.Thread.sleep; |
| 37 | +import static java.util.concurrent.Executors.newFixedThreadPool; |
31 | 38 | import static java.util.concurrent.Executors.newSingleThreadExecutor; |
32 | 39 | import static org.junit.jupiter.api.Assertions.assertEquals; |
33 | 40 | import static org.junit.jupiter.api.Assertions.assertFalse; |
@@ -154,7 +161,7 @@ public void onFileDeleted(FileChangedEvent event) { |
154 | 161 | while (true) { |
155 | 162 | try { |
156 | 163 | deleteDirectory(testDir); |
157 | | - Thread.sleep(500); |
| 164 | + sleep(500); |
158 | 165 | } catch (IOException e) { |
159 | 166 | exception = e; |
160 | 167 | running.set(false); |
@@ -231,25 +238,50 @@ public void testForceDeleteOnIOException() throws Exception { |
231 | 238 | File testDir = createRandomTempDirectory(); |
232 | 239 | File testFile = createRandomFile(testDir); |
233 | 240 |
|
234 | | - ExecutorService executor = newSingleThreadExecutor(); |
| 241 | + int n = 2; |
| 242 | + |
| 243 | + ExecutorService executor = newFixedThreadPool(n); |
| 244 | + |
| 245 | + CompletionService completionService = new ExecutorCompletionService(executor); |
| 246 | + |
| 247 | + // status : 0 -> init |
| 248 | + // status : 1 -> writing |
| 249 | + // status : 2 -> deleting |
| 250 | + AtomicInteger status = new AtomicInteger(0); |
235 | 251 |
|
236 | | - executor.submit(() -> { |
| 252 | + completionService.submit(() -> { |
237 | 253 | synchronized (testFile) { |
238 | | - FileOutputStream outputStream = new FileOutputStream(testFile); |
239 | | - for (int i = 0; i < 10000; i++) { |
240 | | - outputStream.write(i); |
241 | | - // wait for notification |
242 | | - testFile.wait(10); |
243 | | - } |
| 254 | + FileOutputStream outputStream = new FileOutputStream(testFile, true); |
| 255 | + outputStream.write('a'); |
| 256 | + status.set(1); |
| 257 | + // wait for notification |
| 258 | + testFile.wait(); |
244 | 259 | outputStream.close(); |
245 | 260 | } |
246 | 261 | return null; |
247 | 262 | }); |
248 | 263 |
|
249 | | - assertThrows(IOException.class, () -> forceDelete(testFile)); |
| 264 | + completionService.submit(() -> { |
| 265 | + while (status.get() != 1) { |
| 266 | + sleep(10L); |
| 267 | + } |
| 268 | + assertThrows(IOException.class, () -> forceDelete(testFile)); |
| 269 | + status.set(2); |
| 270 | + return null; |
| 271 | + }); |
| 272 | + |
| 273 | + completionService.submit(() -> { |
| 274 | + while (status.get() != 2) { |
| 275 | + sleep(10L); |
| 276 | + } |
| 277 | + synchronized (testFile) { |
| 278 | + testFile.notify(); |
| 279 | + } |
| 280 | + return null; |
| 281 | + }); |
250 | 282 |
|
251 | | - synchronized (testFile) { |
252 | | - testFile.notify(); |
| 283 | + for (int i = 0; i < n; i++) { |
| 284 | + completionService.take().get(); |
253 | 285 | } |
254 | 286 |
|
255 | 287 | executor.shutdown(); |
|
0 commit comments