Skip to content

Commit 9a250c3

Browse files
committed
More links from Dn.2 to other items, don't call a simple ThreadLocal a code smell, expand a comment in a code snippet in Ft.3
1 parent 8d5ccb5 commit 9a250c3

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

README.md

+11-6
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Design
1818
- [Extension API call within a critical section](#non-open-call)
1919
- [Large critical section](#minimize-critical-sections)
2020
- [Waiting in a loop for some result](#justify-busy-wait)
21-
- [`ThreadLocal`, especially when non-static](#threadlocal-design)
21+
- [Non-static `ThreadLocal`](#threadlocal-design)
2222
- [`Thread.sleep()`](#no-sleep-schedule)
2323

2424
Documentation
@@ -62,7 +62,7 @@ Race conditions
6262
](#unsafe-concurrent-iteration)
6363
- [A non-thread-safe collection is *not* returned wrapped in `Collections.unmodifiable*()` from
6464
a getter in a thread-safe class?](#unsafe-concurrent-iteration)
65-
- [Non-trivial object is *not* returned from a getter in a thread-safe class?
65+
- [Non-trivial mutable object is *not* returned from a getter in a thread-safe class?
6666
](#concurrent-mutation-race)
6767
- [No separate getters to an atomically updated state?](#moving-state-race)
6868
- [No *check-then-act* race conditions (state used inside a critical section is read outside of
@@ -250,11 +250,14 @@ https://en.wikipedia.org/wiki/Staged_event-driven_architecture).
250250
**Instance confinement.** Objects of some root type encapsulate some complex hierarchical child
251251
state. Root objects are solitarily responsible for the safety of accesses and modifications to the
252252
child state from multiple threads. In other words, composed objects are synchronized rather than
253-
synchronized objects are composed. See [JCIP 4.2, 10.1.3, 10.1.4]. [TL.4](#tl-instance-chm) touches
254-
on instance confinement of thread-local state.
253+
synchronized objects are composed. See [JCIP 4.2, 10.1.3, 10.1.4].
254+
[RC.3](#unsafe-concurrent-iteration), [RC.4](#concurrent-mutation-race), and
255+
[RC.5](#moving-state-race) describe race conditions that could happen to instance-confined state.
256+
[TL.4](#tl-instance-chm) touches on instance confinement of thread-local state.
255257

256258
**Thread/Task/Serial thread confinement.** Some state is made local to a thread using top-down
257-
pass-through parameters or `ThreadLocal`. See [JCIP 3.3]. Task confinement is a variation of the
259+
pass-through parameters or `ThreadLocal`. See [JCIP 3.3] and [the checklist section about
260+
ThreadLocals](#threadlocal). Task confinement is a variation of the
258261
idea of thread confinement that is used in conjunction with the divide-and-conquer pattern. It
259262
usually comes in the form of lambda-captured "context" parameters or fields in the per-thread task
260263
objects. Serial thread confinement is an extension of the idea of thread confinement for the
@@ -1395,7 +1398,9 @@ Future<Response> makeQuery(String query) {
13951398
} catch (InvalidQueryException e) {
13961399
// Explicit catch preserves the semantics of the original version of makeQuery() most closely.
13971400
// If compile(query) is an expensive computation, it may be undesirable to schedule it to
1398-
// someBlockingIoExecutor() by simply moving compile(query) into the lambda below.
1401+
// someBlockingIoExecutor() by simply moving compile(query) into the lambda below because if
1402+
// this pool has more threads than CPUs then too many compilations might be started in parallel,
1403+
// leading to excessive switches between threads running CPU-bound tasks.
13991404
// Another alternative is scheduling compile(query) to the common FJP:
14001405
// CompletableFuture.supplyAsync(() -> compile(query))
14011406
// .thenApplyAsync(service::remoteCall, someBlockingIoExecutor());

0 commit comments

Comments
 (0)