powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / test synchronized vs ReentrantLock
24 сообщений из 49, страница 2 из 2
test synchronized vs ReentrantLock
    #38436802
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ваш тест некорректен по следующим причинам (включая, но наверняка не ограничиваясь ими):

- переменная counter не используется, т.е., компилятор имеет право выбросить ее, а значит и выбросить циклы. И он это сделает, как только поймет это. Спасет ли чтение волатильной переменной (условие i < N в цикле for), если цикл пустой? Хз, точно сказать не могу.

- нет гарантии, что потоки выполняются параллельно. Система имеет полное право отработать так: сначала отрабатывает 1 и завершается поток, потом второй и тд. При этом видимость одновременного доступа есть, но по факту доступ последовательный, а это значит что кешлайн не гуляет между ядрами, и вы не нарываетесь на такую штуку как flase sharing (в данном случае это корректней обозвать true sharing потому что переменная одна, но механизм тот же). А раз вы на нее не нарываетесь, то примерно раз в 20...100 оно будет работать быстрей.

- для работы снхронизедов надо, чтобы чтобы компилятор собрал профиль и откомпилил код. Пока он этого не сделает, оно может работать хуже.

таким образом вы померяли неверно. У вас что-то померялось, но не то.
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #38436919
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хм... AtomicInteger реализован как вызовы класса Unsafe.
Возможно синхронизация этих сущностей вынесена
из JVM во вне для скорости.

Код: java
1.
2.
3.
4.
public static sun.misc.Unsafe getUnsafe();
public native long objectFieldOffset(java.lang.reflect.Field field);
public native void putOrderedInt(java.lang.Object o, long l, int i);
public final native boolean compareAndSwapInt(java.lang.Object o, long l, int i, int i1);
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #38436925
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton, ты ли это?
Atomic реализованы на CAS на уровне команд процессора. Естественно никакой Java API для этого не используется. Только натив.
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #38436981
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это я. И это просто рассуждения вслух. Просто разбираясь с оптимизацией перформанса
полезно знать стек. Тоесть что чего вызывает и что от чего зависит. ТС-у полезно также
знать что механизмы синхронизации Java построенные на других механизмах Java вряд-ли
дадут ему особый прирост скорости.
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #38438953
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapokваш тест некорректен по следующим причинам (включая, но наверняка не ограничиваясь ими):

- переменная counter не используется, т.е., компилятор имеет право выбросить ее, а значит и выбросить циклы. И он это сделает, как только поймет это. Спасет ли чтение волатильной переменной (условие i < N в цикле for), если цикл пустой? Хз, точно сказать не могу.




Жду от вас корректного теста и результатов :)
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #38438984
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1Жду от вас корректного теста и результатов :)Коллега, вы совершенно зря язвите. Вы будете удивлены, но написать качественный многопоточный бенчмарк какого-нибудь реального сценария, в котором есть СУБД, сокеты, работа с файловой системой, и прочие прелести, в разы проще , чем написать качественный бенчмарк, который измерит какой-нибудь volatile vs non-volatile или synchronized vs ReentrantLock. Еще раз акцентирую ваше внимание: в разы проще .
Это как в физике. Когда вы рассматриваете тела макроскопически, то это обычная материя, к которой применимы, например, законы Ньютона. Но когда вы спускаетесь на квантовый уровень, вы сразу же начинаете охреневать от неопределенности Гейзенберга, корпусклуярно-волнового Дуализма и прочих "прелестей". В микромире законы маркомира не работают. Микромир значительно сложнее.
И Java тут не является исключением. Если хотите лучше понимать, что происходит на таких уровнях, то рекомендую вам сделать следующее:
1) Почитать Java Concurreny in Practice - для разгона
2) Почитать The Art of Multiprocessor Programming - что бы понимать, как создавали классы из java.util.concurrent, тут уже ягодки идут
3) Почитать папИр Дага Ли, в котором он рассказывает, как создавался AbstractQueueSynchronzer: http://gee.cs.oswego.edu/dl/papers/aqs.pdf
4) Подписаться на мэилинг-лист concurrency-interest
5) Посмотреть презенташки по многопоточности из JUG.RU: http://vk.com/jugru
6) Почитать и пощупать Шипилевский JMH.

Вот когда сделаете это, тогда и будете здесь подстебывать мемберов, и пытаться брать их "на слабо". А сейчас "слабо" вам, так что лучше не отвергать предлагаемую помощь, и слушать советы.
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #38438991
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjv,
обычно уже на 3-4 пункте начинаешь осознавать свою неполноценность:)
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #38438997
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjvМикромир значительно сложнееПроще. Но от этого не легче.
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #38439010
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjvВот когда сделаете это, тогда и будете здесь подстебывать мемберов, и пытаться брать их "на слабо". А сейчас "слабо" вам, так что лучше не отвергать предлагаемую помощь, и слушать советы.

Да я и не подстебывал .

все замечания описанные выше имеют место быть.

А так же опираясь на Ваш тезис о микромире - можно сказать след. А что мешает :

А) переменная counter не используется - а может и используется. или сделать простую проверку чтобы она использовалась.
Б) нет гарантии, что потоки выполняются параллельно - но и нет опровержения.
В) для работы снхронизедов надо, чтобы чтобы компилятор собрал профиль и откомпилил код - если добавить более четкие параметры для кода - получим точно такую же ситуацию - исходя из пунктов А и Б.

Это JAVAAAA (c) - тут вообще нет честных тестов :)
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #38439972
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1,
От меня корректного теста не будет, по той причине что я сам пока не знаю как это померять.
Когда-то скачивал jmh - и не понял его. Документировано там все слабовато, и есть самоисключающие примеры. Самоисключающие - это когда результаты теста противоречат сами себе. Так и не понял, как им пользоваться. Верней, как пользоваться ясно, но как правильно написать тест и померять именно то, что я хочу - неясно.

И судя по тому как вы злитесь, подстебнули не вы меня, а я вас. :) Сам меряю производительность так: пишутся варианты реальной программы и ей подсовываю данные близкие к реальным. На микроуровне я уже понял, что тестить что-то бесполезно.

Насчет используется/не используется тоже не все так очевидно. На самом деле, использовать переменную просто - выводим ее на печать.
Только такое использование спасет от оптимизации "выбрасывания", но не спасет от оптимизации анролинга циклов, например. А просто использование проверкой тоже может быть оптимизировано, если оно не несет смысловой нагрузки.

> Б) нет гарантии, что потоки выполняются параллельно - но и нет опровержения.
вот я и говорю - мы меряем непонятно что.
из личных практических наблюдеий - если есть 10 потоков, то эти потоки по факту стартуют не в той последовательности как их запускаешь в цикле.
Следовательно, как минимум, часть инкрементов была выполнена без реальной конкуренции за данные, а значит и завершение потоков было не одновременным на сколько-то. Это с высокой вероятностью можно предполагать.

ps. Посмотрите исходники ReentrantLock, может накопаете чего интересного.
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #38439982
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapokОт меня корректного теста не будет, по той причине что я сам пока не знаю как это померять.

Что-то ты перемудрил. И так везде пишут что при высокрой нагруженности ReentrantLock более производительный чем synchronized, что тест выше и показал. Но в реальности это ничего не даёт. Так как подобная конкуренция встречается не часто. А при низкой конкурентности synchronized покажет лучшие результаты.
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #38442798
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

Я не перемудрил, я привык критически смотреть на то, что пишут в интернете, выборочно проверяя (в том числе с целью самообучения) некоторые утверждения. Да, ReentrantLock, да пишут. Но как повторить самому это дома - я незнаю, о чем и сообщил.
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #38444721
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapokНо как повторить самому это дома -

Ну создаешь
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
class Incrementer{

 private long value=-1l;

 public long synchronized inc() {
  return (++value);
 }

}



Массивчик на 1000 инкрементеров. И два потока которые много раз пробегают по массиву (в разные стороны) и вызывают inc().

И тоже самое через Lock.

Встречаться они должны не часто - вот и низкая конкуренция.
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #38671049
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Возник такой вопрос : а как построить самый быстрый счетчик - инкремент ,
который будет безопасно работать многопоточной среде ?

что то есть быстрее AtomicInteger ?
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #38671052
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1Возник такой вопрос : а как построить самый быстрый счетчик - инкремент ,
который будет безопасно работать многопоточной среде ?

что то есть быстрее AtomicInteger ?
Есть. Каждому потоку выдать по своему счетчику и в конце просуммировать по всем потокам. На сколько я помню, должно быть быстрее AtomicInteger.
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #38671059
DEVcoach
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Atum1 , LongAdder.
Основан на другом принципе - инкременты с разных потоков идут в разные переменные, тем самым снижая contention. А когда надо получить сумму - просто проходим по ним, и суммируем. Для точных вычислений он не пригоден, но очень резв.

С другой стороны, начиная с Java7 для CASов стандартных атомиков сделаны интринсики, которые устремляют к нулю количество "обломов" на одновременных CAS-ах с разных потоков, поэтому с выходом Java7 атомики стали заметно шустрее на некоторых платформах, включая наш родной x86.
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #38671063
DEVcoach
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вернее, не для самих CASов, а для некоторых других методов, которые основаны на них. Например, incrementAndGet(), addAndGet() и т.д..
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #38671068
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
О! спасибо!

как раз нашел

https://github.com/takipi/counters-benchmark/tree/master/src/main/java/com/takipi/tests/counters/implementations

и описание :

http://www.takipiblog.com/2014/04/16/java-8-longadders-the-fastest-way-to-add-numbers-concurrently/

видимо не я один такими вопросами задаюсь :)
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #38671121
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вспомнив, что ускорение на порядок куска кода, занимающего десять процентов общего времени даёт (всего) девять процентов выигрыша, начинаешь прикидывать - стОит ли вообще овчинка выделки?..
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #38671770
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov,

ну хз.... может в торговых система и имеет :)
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
test synchronized vs ReentrantLock
    #39015160
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кто может объяснить на каких операциях будет разница между этими типами :


AtomicInteger vs LongAdder vs LongAccumulator

http://winterbe.com/posts/2015/05/22/java8-concurrency-tutorial-atomic-concurrent-map-examples/

написал тест такого плана - разницу не увидел , почему ?

только от N=10000000 - но там и погрешность есть ...


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.LongAccumulator;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.LongBinaryOperator;
import java.util.stream.IntStream;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

@Warmup(iterations = 5)
@Measurement(iterations = 10)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
@Fork(2)
public class Sum {

    public static void stop(ExecutorService executor) {
        try {
            executor.shutdown();
            executor.awaitTermination(60, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            System.err.println("termination interrupted");
        } finally {
            if (!executor.isTerminated()) {
                System.err.println("killing non-finished tasks");
            }
            executor.shutdownNow();
        }
    }

    public static int fori(int n) {

        long sum = 0;
        for (int i = 0; i < n; i++) {
            sum += i;

        }

        return (int) sum;
    }

    public static int longAdder(int n) {
        LongAdder adder = new LongAdder();

        ExecutorService executor = Executors.newFixedThreadPool(4);

        IntStream.range(0, n)
                .forEach(i -> executor.submit(adder::increment));

        stop(executor);

        return adder.intValue();
    }

    public static int atomicInteger(int n) {
        AtomicInteger atomicInt = new AtomicInteger(0);

        ExecutorService executor = Executors.newFixedThreadPool(4);

        IntStream.range(0, n)
                .forEach(i -> executor.submit(atomicInt::incrementAndGet));

        stop(executor);

        return atomicInt.intValue();
    }

    public static int longAccumulator(int n) {

        LongBinaryOperator op = (x, y) -> x + y;

        LongAccumulator accumulator = new LongAccumulator(op, 1L);;

        ExecutorService executor = Executors.newFixedThreadPool(4);

        IntStream.range(0, n)
                .forEach(i -> executor.submit(() -> accumulator.accumulate(i)));

        stop(executor);

        return accumulator.intValue();
    }

    @Param({"1000", "10000", "100000", "1000000", "10000000"})
    private int n;

    @Benchmark
    public void testLongAdder(Blackhole bh) {
        bh.consume(longAdder(n));
    }

    @Benchmark
    public void testAtomicInteger(Blackhole bh) {
        bh.consume(atomicInteger(n));
    }

    @Benchmark
    public void testLongAccumulator(Blackhole bh) {
        bh.consume(longAccumulator(n));
    }
    @Benchmark
    public void testFori(Blackhole bh) {
        bh.consume(fori(n));
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(Sum.class.getSimpleName())
                .forks(1)
                .build();

        new Runner(opt).run();
    }

}





Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
# Run complete. Total time: 00:07:44

Benchmark                     (n)  Mode  Cnt     Score      Error  Units
Sum.testAtomicInteger        1000  avgt   10     0,536 ±    0,022  ms/op
Sum.testAtomicInteger       10000  avgt   10     2,737 ±    0,087  ms/op
Sum.testAtomicInteger      100000  avgt   10    20,559 ±    1,064  ms/op
Sum.testAtomicInteger     1000000  avgt   10   206,458 ±   18,769  ms/op
Sum.testAtomicInteger    10000000  avgt   10  5101,871 ± 1605,404  ms/op
Sum.testFori                 1000  avgt   10    &#8776; 10&#8315;&#179;             ms/op
Sum.testFori                10000  avgt   10     0,004 ±    0,001  ms/op
Sum.testFori               100000  avgt   10     0,043 ±    0,001  ms/op
Sum.testFori              1000000  avgt   10     0,430 ±    0,010  ms/op
Sum.testFori             10000000  avgt   10     4,281 ±    0,018  ms/op
Sum.testLongAccumulator      1000  avgt   10     0,524 ±    0,013  ms/op
Sum.testLongAccumulator     10000  avgt   10     2,540 ±    0,064  ms/op
Sum.testLongAccumulator    100000  avgt   10    19,878 ±    1,078  ms/op
Sum.testLongAccumulator   1000000  avgt   10   210,660 ±    9,564  ms/op
Sum.testLongAccumulator  10000000  avgt   10  3238,301 ±  400,139  ms/op
Sum.testLongAdder            1000  avgt   10     0,539 ±    0,039  ms/op
Sum.testLongAdder           10000  avgt   10     2,655 ±    0,097  ms/op
Sum.testLongAdder          100000  avgt   10    21,172 ±    0,839  ms/op
Sum.testLongAdder         1000000  avgt   10   215,976 ±   16,169  ms/op
Sum.testLongAdder        10000000  avgt   10  3712,276 ± 1076,237  ms/op
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #39015962
Фотография schwa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1,

Разницы не видно из-за того, что бенчамарк тестирует не счетчики, а создание и остановку потоков.
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #39016830
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
schwaAtum1,

Разницы не видно из-за того, что бенчамарк тестирует не счетчики, а создание и остановку потоков.


???
...
Рейтинг: 0 / 0
test synchronized vs ReentrantLock
    #39017236
Фотография schwa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1,

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
 @Benchmark
    public void testLongAdder(Blackhole bh) {
        LongAdder adder = new LongAdder();

        ExecutorService executor = Executors.newFixedThreadPool(4); // 1

        IntStream.range(0, n)
                .forEach(i -> executor.submit(adder::increment)); // 2

        stop(executor); // 3

       bh.consume(accumulator.longValue();
}


Что делает этот код?
1 - создать 4 потока
2 - выполнить какой-то код в 4 потоках
3 - остановить потоки

Шаги 1 и 3 в сумме съедают больше времени, чем суммирование счетчиков.
Из-за того, что у вашем бенчмарке фиксированное число потоков (при этом очень маленькое), вы иногируете тот факт, что классы LongAdder и LongAccumulator разработаны для совершенно иной ситуации - когда потоков много и они соревнуются между собой за одну единствунную ячейку памяти.

Вот результат бенчмарка, запущенного на n1-standard x16 CPU виртуалке на Google Compute Engine
Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
# Run complete. Total time: 00:04:22

Benchmark                         Mode  Cnt          Score         Error  Units
CountersBenchmark.al_x02         thrpt   10   45135864.893 ? 1185034.673  ops/s
CountersBenchmark.al_x04         thrpt   10   38169882.884 ?   51139.952  ops/s
CountersBenchmark.al_x08         thrpt   10   37985227.786 ?  131890.714  ops/s
CountersBenchmark.al_x16         thrpt   10   52128402.365 ?  240725.555  ops/s
CountersBenchmark.al_x32         thrpt   10   64183053.929 ?  322331.204  ops/s
CountersBenchmark.al_x64         thrpt   10   56510534.133 ?  485246.626  ops/s
CountersBenchmark.longAdder_x02  thrpt   10  175008499.380 ?  487533.370  ops/s
CountersBenchmark.longAdder_x04  thrpt   10  342938648.209 ? 1248616.682  ops/s
CountersBenchmark.longAdder_x08  thrpt   10  491676490.764 ? 6343110.926  ops/s
CountersBenchmark.longAdder_x16  thrpt   10  492169577.462 ? 2963772.754  ops/s
CountersBenchmark.longAdder_x32  thrpt   10  494638487.463 ? 3466056.114  ops/s
CountersBenchmark.longAdder_x64  thrpt   10  496521481.868 ? 4182585.045  ops/s



Характеристики виртуалки

$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 8
On-line CPU(s) list: 0-7
Thread(s) per core: 2
Core(s) per socket: 4
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 45
Model name: Intel(R) Xeon(R) CPU @ 2.60GHz
Stepping: 7
CPU MHz: 2600.000
BogoMIPS: 5200.00
Hypervisor vendor: KVM
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 20480K
NUMA node0 CPU(s): 0-7


Сам бенчмарк, не претендует на идеал, но по крайней мере здесь всеми потоками рулит JMH и, следовательно, числа в итогом отчете содержат минимум шума. Можно запустить побольше форков и поиграться со счетчиком в цикле, но отличия в производительности уже и так есть (что не удивительно).


java -jar target/benchmarks.jar -wi 10 -i 10 -f 1

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
package playground;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.OperationsPerInvocation;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.infra.Blackhole;

import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;

public class CountersBenchmark {

    @State(Scope.Benchmark)
    public static class LongA {

        final LongAdder adder = new LongAdder();
    }

    @State(Scope.Benchmark)
    public static class AtomicL {

        final AtomicLong aLong = new AtomicLong();
    }

    @Benchmark
    @OperationsPerInvocation(1000)
    @Threads(2)
    public void al_x02(AtomicL a, Blackhole bh) {
        add(a, bh);
    }

    @Benchmark
    @OperationsPerInvocation(1000)
    @Threads(4)
    public void al_x04(AtomicL a, Blackhole bh) {
        add(a, bh);
    }

    @Benchmark
    @OperationsPerInvocation(1000)
    @Threads(8)
    public void al_x08(AtomicL a, Blackhole bh) {
        add(a, bh);
    }

    @Benchmark
    @OperationsPerInvocation(1000)
    @Threads(16)
    public void al_x16(AtomicL a, Blackhole bh) {
        add(a, bh);
    }

    @Benchmark
    @OperationsPerInvocation(1000)
    @Threads(32)
    public void al_x32(AtomicL a, Blackhole bh) {
        add(a, bh);
    }

    @Benchmark
    @OperationsPerInvocation(1000)
    @Threads(64)
    public void al_x64(AtomicL a, Blackhole bh) {
        add(a, bh);
    }

    @Benchmark
    @OperationsPerInvocation(1000)
    @Threads(2)
    public void longAdder_x02(LongA a, Blackhole bh) {
        add(a, bh);
    }

    @Benchmark
    @OperationsPerInvocation(1000)
    @Threads(4)
    public void longAdder_x04(LongA a, Blackhole bh) {
        add(a, bh);
    }

    @Benchmark
    @OperationsPerInvocation(1000)
    @Threads(8)
    public void longAdder_x08(LongA a, Blackhole bh) {
        add(a, bh);
    }

    @Benchmark
    @OperationsPerInvocation(1000)
    @Threads(16)
    public void longAdder_x16(LongA a, Blackhole bh) {
        add(a, bh);
    }

    @Benchmark
    @OperationsPerInvocation(1000)
    @Threads(32)
    public void longAdder_x32(LongA a, Blackhole bh) {
        add(a, bh);
    }

    @Benchmark
    @OperationsPerInvocation(1000)
    @Threads(64)
    public void longAdder_x64(LongA a, Blackhole bh) {
        add(a, bh);
    }

    private void add(LongA a, Blackhole bh) {
        for (int i = 0; i < 1000; i ++) {
            a.adder.increment();
        }
        bh.consume(a.adder.longValue());
    }

    private void add(AtomicL a, Blackhole bh) {
        for (int i = 0; i < 1000; i ++) {
            a.aLong.incrementAndGet();
        }
        bh.consume(a.aLong.longValue());
    }
}


...
Рейтинг: 0 / 0
24 сообщений из 49, страница 2 из 2
Форумы / Java [игнор отключен] [закрыт для гостей] / test synchronized vs ReentrantLock
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]