@@ -116,7 +116,7 @@ Improving scalability
116116 - [ Critical section is as small as possible?] ( #minimize-critical-sections )
117117 - [ Can use ` ConcurrentHashMap.compute() ` or Guava's ` Striped ` for per-key locking?
118118 ] ( #increase-locking-granularity )
119- - [ Can replace blocking collection or a queue with a concurrent one?] ( #non-blocking-collections )
119+ - [ Can replace a blocking collection or a queue with a concurrent one?] ( #non-blocking-collections )
120120 - [ Can use ` ClassValue ` instead of ` ConcurrentHashMap<Class, ...> ` ?] ( #use-class-value )
121121 - [ Considered ` ReadWriteLock ` (or ` StampedLock ` ) instead of a simple lock?] ( #read-write-lock )
122122 - [ ` StampedLock ` is used instead of ` ReadWriteLock ` when reentrancy is not needed?
@@ -126,6 +126,7 @@ Improving scalability
126126 - [ Considered queues from JCTools instead of the standard concurrent queues?] ( #jctools )
127127 - [ Considered Caffeine cache instead of other caching libraries?] ( #caffeine )
128128 - [ Can apply speculation (optimistic concurrency) technique?] ( #speculation )
129+ - [ Considered ` ForkJoinPool ` instead of ` newFixedThreadPool(N) ` ?] ( #fjp-instead-tpe )
129130
130131Lazy initialization and double-checked locking
131132 - [ Lazy initialization of a field should be thread-safe?] ( #lazy-init-thread-safety )
@@ -1001,9 +1002,13 @@ blocking ones?** Here are some possible replacements within JDK:
10011002 - ` LinkedBlockingQueue ` → ` ConcurrentLinkedQueue `
10021003 - ` LinkedBlockingDeque ` → ` ConcurrentLinkedDeque `
10031004
1004- Also consider using queues from JCTools instead of concurrent queues from the JDK: see
1005+ Consider also using queues from JCTools instead of concurrent queues from the JDK: see
10051006[ Sc.8] ( #jctools ) .
10061007
1008+ See also an item about using [ ` ForkJoinPool ` instead of ` newFixedThreadPool(N) ` ] ( #fjp-instead-tpe )
1009+ for high-traffic executor services, which internally amounts to replacing a single blocking queue of
1010+ tasks inside ` ThreadPoolExecutor ` with multiple non-blocking queues inside ` ForkJoinPool ` .
1011+
10071012<a name =" use-class-value " ></a >
10081013[ #] ( #use-class-value ) Sc.4. Is it possible to ** use [ ` ClassValue ` ] (
10091014https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ClassValue.html ) instead of
@@ -1077,6 +1082,21 @@ This principle is used internally in many scalable concurrent data structures, i
10771082See also the article about [ Optimistic concurrency control] (
10781083https://en.wikipedia.org/wiki/Optimistic_concurrency_control ) on Wikipedia.
10791084
1085+ <a name =" fjp-instead-tpe " ></a >
1086+ [ #] ( #fjp-instead-tpe ) Sc.11. Was it considered to ** use a ` ForkJoinPool ` instead of a
1087+ ` ThreadPoolExecutor ` with N threads** (e. g. returned from one of ` Executors.newFixedThreadPool() `
1088+ methods), for thread pools on which a lot of small tasks are executed? ` ForkJoinPool ` is more
1089+ scalable because internally it maintains one queue per each worker thread, whereas
1090+ ` ThreadPoolExecutor ` has a single, blocking task queue shared among all threads.
1091+
1092+ ` ForkJoinPool ` implements ` ExecutorService ` as well as ` ThreadPoolExecutor ` , so could often be a
1093+ drop in replacement. For caveats and details, see [ this] (
1094+ http://cs.oswego.edu/pipermail/concurrency-interest/2020-January/017058.html ) and [ this] (
1095+ http://cs.oswego.edu/pipermail/concurrency-interest/2020-February/017061.html ) messages by Doug Lea.
1096+
1097+ See also items about [ using non-blocking collections (including queues) instead of blocking
1098+ ones] ( #non-blocking-collections ) and about [ using JCTools queues] ( #jctools ) .
1099+
10801100<a name =" lazy-init " ></a >
10811101### Lazy initialization and double-checked locking
10821102
0 commit comments