package com.learning.atomic;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
/**
 * @Description 原子数组
 */
public class AtomicArrayLearning {
    public static void main(String[] args) {
        demo(
        		// 普通数组
                ()->new int[10],
                (array)->array.length,
                (array, index)->array[index]++,
                array-> System.out.println(Arrays.toString(array))
        );
        demo(
                // 原子数组
                ()->new AtomicIntegerArray(10),
                (atomicIntegerArray) -> atomicIntegerArray.length(),
                (atomicIntegerArray, index) -> atomicIntegerArray.getAndIncrement(index),
                atomicIntegerArray -> System.out.println(atomicIntegerArray)
        );
    }
    
    public static <T> void demo(
            Supplier<T> arraySupplier,
            Function<T, Integer> lengthFunction,
            BiConsumer<T, Integer> putConsumer,
            Consumer<T> printConsumer
    ){
        List<Thread> threadList = new ArrayList<>();
        T array = arraySupplier.get();
        int length = lengthFunction.apply(array);
        for (int i = 0; i < length; i++) {
            // 每个线程对数组操作10000次
            threadList.add(new Thread(()->{
                for(int j = 0;j < 10000; j++){
                    putConsumer.accept(array, j % length);
                }
            }));
        }
        threadList.forEach(t->t.start());
        threadList.forEach(t-> {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        printConsumer.accept(array);
    }
}