Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit de24241

Browse files
committed
Add TE.8 about ScheduledExecutorService and Thread.sleep(), fixes #13
1 parent 3ec1afd commit de24241

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

‎README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ Threads and Executors
157157
- the future is completed and the callback is attached from the same thread pool?
158158
- [Adding a callback to a `CompletableFuture` (`SettableFuture`) in non-async mode is justified?
159159
](#cf-beware-non-async)
160+
- [Actions are delayed via a `ScheduledExecutorService` rather than `Thread.sleep()`?
161+
](#no-sleep-schedule)
160162

161163
Parallel Streams
162164
- [Parallel Stream computation takes more than 100us in total?](#justify-parallel-stream-use)
@@ -1172,6 +1174,8 @@ execution mode* (via methods like `thenAccept()`, `thenApply()`, `handle()`, etc
11721174
inadvertently lead to performing them in `ForkJoinPool` from where the future may be completed: see
11731175
[TE.7](#cf-beware-non-async).
11741176

1177+
`Thread.sleep()` is a blocking operation.
1178+
11751179
This advice should not be taken too far: occasional transient IO (such as that may happen during
11761180
logging) and operations that may rarely block (such as `ConcurrentHashMap.put()` calls) usually
11771181
shouldn’t disqualify all their callers from execution in a `ForkJoinPool` or in a parallel `Stream`.
@@ -1246,6 +1250,22 @@ See also the Javadoc for [`ListenableFuture.addListener()`](
12461250
https://guava.dev/releases/28.1-jre/api/docs/com/google/common/util/concurrent/ListenableFuture.html#addListener-java.lang.Runnable-java.util.concurrent.Executor-
12471251
) describing this problem.
12481252

1253+
<a name="no-sleep-schedule"></a>
1254+
[#](#no-sleep-schedule) TE.8. **A task or action is executed with a delay via a
1255+
[`ScheduledExecutorService`](
1256+
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/ScheduledExecutorService.html)
1257+
rather than by calling `Thread.sleep()` before performing the work** or submitting the task to
1258+
an executor? `ScheduledExecutorService` allows to execute many such tasks on a small number of
1259+
threads, while the approach with `Thread.sleep` requires a dedicated thread for every delayed
1260+
action. Sleeping in the context of an unknown executor (if there is insufficient *concurrent access
1261+
documentation* for the method, as per [Dc.1](#justify-document), or if this is a
1262+
concurrency-agnostic library method) before submitting the task to an executor is also bad: the
1263+
context executor may not tolerate blocking calls such as `Thread.sleep`, see
1264+
[TE.4](#fjp-no-blocking) for details.
1265+
1266+
This item equally applies to scheduling one-shot and recurrent delayed actions, there are methods
1267+
for both scenarios in `ScheduledExecutorService`.
1268+
12491269
### Parallel Streams
12501270

12511271
<a name="justify-parallel-stream-use"></a>

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /