[
https://issues.apache.org/jira/browse/ZOOKEEPER-2790?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16030527#comment-16030527
]
Benedict Jin commented on ZOOKEEPER-2790:
-----------------------------------------
Hi [~abrahamfine]. Yep, you are right. But, there is a little problem that
`LongAdder` will not initialize `Cell[]` array and it will save the memory due
to the lazy initialization in low contention case. In my opinion, there are
three reasons for using it:
* High Performance in High Contention
From the architectural point of view, `AtomicLong` uses a single variable`
volatile long` 'and `Cell []` in `LongAdder`, which distributes concurrent
stress to the entire array, not A single variable can be more handy to deal
with high concurrent scenes.
* Low Resource Consumption
`Cell []` array is delayed initialization, and in the expansion of the
operation, is taking into account the CPU's core (ie, the processing power of
the machine) and array operations of the number of collisions (that is, the
degree of concurrency) Optimize the use of resources as much as possible.
* More Efficient Assembly Instructions
Using the `lock xadd` rather than `lock cmpxchg` instructions to achieve
atomic operation, to avoid the CAS ABA problem, high co-continuous spin caused
by excessive consumption of CPU resources, predict the failure of branches and
other issues.
> Should we consider using `LongAdder` instead of `AtomicLong`
> -------------------------------------------------------------
>
> Key: ZOOKEEPER-2790
> URL: https://issues.apache.org/jira/browse/ZOOKEEPER-2790
> Project: ZooKeeper
> Issue Type: Improvement
> Components: server
> Affects Versions: 3.5.3
> Reporter: Benedict Jin
> Fix For: 4.0.0
>
>
> ```java
> // -Xmx512M -Xms512M -Xmn256M -XX:+AlwaysPreTouch -ea
> @Test
> public void pressureLongAdder() throws Exception {
> final LongAdder longAdder = new LongAdder();
> ExecutorService executorService = Executors.newCachedThreadPool();
> long startTime = System.currentTimeMillis();
> for (int i = 0; i < 100; i++) {
> executorService.submit(new Thread(() -> {
> for (int j = 0; j < 1000_0000; j++) {
> longAdder.increment();
> }
> System.out.print(String.format("%s %s \t",
> Thread.currentThread().getId(), longAdder.longValue()));
> /*
> 14 19607585 12 36445036 20 38985288 38 76821270
> 70 117094732 18 127252576
> 22 137043349 26 153411172 30 164051380 34 165971155
> 102 192241678 134 201104979
> 158 232657818 46 279030056 174 288502545 94 347965290
> 198 348060553 118 348087414
> 36 353092712 28 357762215 44 365464475 126 379518198
> 54 379623515 182 380077075
> 142 385263911 78 389013887 62 389085727 110 389122678
> 86 389920423 166 393535019
> 150 396382512 190 403100499 32 403161217 208 403197689
> 206 406065520 16 410725026
> 24 415347205 40 415379997 48 415733397 104 418507295
> 192 423244160 176 455793362
> 168 458311865 160 463028656 136 496375440 72 541243645
> 186 561877000 170 575352229
> 162 584152392 154 604552121 138 614092854 64 638151890
> 114 668705836 58 669235250
> 188 699213410 156 729222401 124 754336889 100 784326386
> 76 813479501 120 827569944
> 66 830236567 98 832153503 112 841408676 204 849520891
> 210 852391130 202 864804732
> 172 875603834 194 877222893 200 881090909 88 882809513
> 80 882846368 56 887174571
> 178 889682247 140 901357028 146 902169049 184 904540678
> 152 915608988 130 917896629
> 116 924616135 144 927674541 122 930399321 128 939791111
> 106 942656234 84 950848174
> 96 951904067 90 954910184 74 964338213 196 966487766
> 82 968307139 52 975854400
> 180 977385398 164 978882525 50 980896807 148 988292352
> 132 989090669 108 996891232
> 92 996921398 42 996938988 68 996953941 60 1000000000
> */
> }));
> }
> executorService.shutdown();
> while (!executorService.isTerminated()) {
> Thread.sleep(1);
> }
> long endTime = System.currentTimeMillis();
> System.out.println("\n" + (endTime - startTime)); // 3275 ms
> }
> // -Xmx512M -Xms512M -Xmn256M -XX:+AlwaysPreTouch -ea
> @Test
> public void pressureAtomicLong() throws Exception {
> final AtomicLong atomicLong = new AtomicLong();
> ExecutorService executorService = Executors.newCachedThreadPool();
> long startTime = System.currentTimeMillis();
> for (int i = 0; i < 100; i++) {
> executorService.submit(new Thread(() -> {
> for (int j = 0; j < 1000_0000; j++) {
> atomicLong.getAndIncrement();
> }
> System.out.print(String.format("%s %s \t",
> Thread.currentThread().getId(), atomicLong.longValue()));
> /*
> 12 390000000 28 390000000 44 390000000 20 390000000
> 26 390000000 18 390000000
> 80 390000000 56 390000000 96 390000000 24 390000000
> 88 390000000 72 390000000
> 22 390000000 118 390000000 54 390000000 142 390000000
> 70 390000000 86 390000000
> 182 390000000 110 390000000 62 390000000 78 390000000
> 102 390000000 158 390000000
> 150 390000000 46 390000000 38 390000000 126 390000000
> 94 390000000 134 390000000
> 14 390000000 48 390000000 40 390000000 32 390000000
> 34 390000000 64 390000000
> 42 390000000 36 390000000 16 390000000 180 416396554
> 204 419908287 196 425536497
> 92 732203658 30 733835560 202 733835559 210 733873571
> 146 733878564 186 733883527
> 170 733888686 76 733892691 84 733888815 148 733901560
> 162 733907032 172 733908079
> 52 733913280 116 733918421 124 733906868 164 733920945
> 132 733891348 68 733923672
> 108 733924928 156 733926091 60 733921998 140 733927257
> 188 733928891 154 733871822
> 194 733830477 178 733872527 100 733830322 106 748251688
> 144 1000000000 98 1000000000
> 58 1000000000 90 1000000000 130 1000000000 138 1000000000
> 114 1000000000 104 1000000000
> 168 1000000000 200 1000000000 184 1000000000 160 1000000000
> 174 1000000000 112 1000000000
> 190 1000000000 198 1000000000 82 1000000000 206 1000000000
> 166 1000000000 176 1000000000
> 136 1000000000 208 1000000000 74 1000000000 122 1000000000
> 152 1000000000 192 1000000000
> 120 1000000000 128 1000000000 66 1000000000 50 1000000000
> */
> }));
> }
> executorService.shutdown();
> while (!executorService.isTerminated()) {
> Thread.sleep(1);
> }
> long endTime = System.currentTimeMillis();
> System.out.println("\n" + (endTime - startTime)); // 19409 ms
> }
> ```
--
This message was sent by Atlassian JIRA
(v6.3.15#6346)