当前位置:网站首页>Multithreading tutorial (XXVI) field updater and atomic accumulator

Multithreading tutorial (XXVI) field updater and atomic accumulator

2022-06-11 05:29:00 Have you become a great God today

Multithreading tutorial ( hexacosa- ) Field updater 、 Atomic accumulator

One 、 Field updater

Common field updaters :

  • AtomicReferenceFieldUpdater // Domain Field

  • AtomicIntegerFieldUpdater

  • AtomicLongFieldUpdater

Using field Updater , You can target a domain of the object (Field) Perform atomic operations , Can only cooperate with volatile Modified field usage , Otherwise, there will be an exception

Exception in thread "main" java.lang.IllegalArgumentException: Must be volatile type

Example :

public class Test5 {
    
    private volatile int field;
    public static void main(String[] args) {
    
        AtomicIntegerFieldUpdater fieldUpdater =
            AtomicIntegerFieldUpdater.newUpdater(Test5.class, "field");
        Test5 test5 = new Test5();
        fieldUpdater.compareAndSet(test5, 0, 10);
        //  Modification successful  field = 10
        System.out.println(test5.field);
        //  Modification successful  field = 20
        fieldUpdater.compareAndSet(test5, 10, 20);
        System.out.println(test5.field);
        //  Modification failed  field = 20
        fieldUpdater.compareAndSet(test5, 10, 30);
        System.out.println(test5.field);
    }
}

Output

10 
20 
20

Two 、 Atomic accumulator

The atomic accumulator mainly solves the problem of multithreading i++ Thread insecurity

1. Accumulator performance comparison

private static <T> void demo(Supplier<T> adderSupplier, Consumer<T> action) {
    
    T adder = adderSupplier.get();
    long start = System.nanoTime();
    List<Thread> ts = new ArrayList<>();
    // 4  Threads , Everyone adds up  50  ten thousand 
    for (int i = 0; i < 40; i++) {
    
        ts.add(new Thread(() -> {
    
            for (int j = 0; j < 500000; j++) {
    
                action.accept(adder);
            }
        }));
    }
    ts.forEach(t -> t.start());
    ts.forEach(t -> {
    
        try {
    
            t.join();
        } catch (InterruptedException e) {
    
            e.printStackTrace();
        }
    });
    long end = System.nanoTime();
    System.out.println(adder + " cost:" + (end - start)/1000_000);
}

Compare AtomicLong And LongAdder

for (int i = 0; i < 5; i++) {
    
    demo(() -> new LongAdder(), adder -> adder.increment());
}
for (int i = 0; i < 5; i++) {
    
    demo(() -> new AtomicLong(), adder -> adder.getAndIncrement());
}

Output

1000000 cost:43 
1000000 cost:9 
1000000 cost:7 
1000000 cost:7 
1000000 cost:7 
1000000 cost:31 
1000000 cost:27 
1000000 cost:28 
1000000 cost:24 
1000000 cost:22

The reason for the performance improvement is simple , It's when there's competition , Set multiple accumulation units ,Therad-0 Add up Cell[0], and Thread-1 Add up Cell[1]… Finally, summarize the results . In this way, they operate differently when accumulating Cell Variable , Therefore, it is reduced CAS Retry fail , To improve performance .

LongAdder The design is very clever , If you are interested, you can take a look at his code and design principles , I won't introduce you here . The most important pseudo sharing will be introduced later .

原网站

版权声明
本文为[Have you become a great God today]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/03/202203020539055717.html