A, LongAdder
LongAdder is JDK8 inAtomicLong的增强工具类,它与
AtomicLong
最大的不同就是:在多线程场景下,LongAdder中对单一的变量进行拆分成多个变量,这些变量分为两类base和Cell。base是基础值,默认一般为0;而Cell就是我们所拆分的值,它可以有多个。所以当获取LongAdder的值时就是把base
和每个Cell的值相加。
Why split into multiple Cell
it? This is because in a multithreaded scenario, if multiple threads are operating on the same variable, in order to make this variable atomicity, we have to play lock, thus greatly reducing the performance of the program. But if this variable is split into multiple Cell, each Cell will though still locked, but the threads access the variable is not the same, you can perform asynchronous operations.
About Cell features:
1.Cell using lazy loading mechanism, because the Cell occupy memory space is relatively large. Will begin to create Base, only when there are other threads to compete for resources, it will be split into multiple Cell;
2.Cell initialization is 2, each expansion N is a power of 2;
3.Cell is essentially an array whose elements is a maximum number of CPU cores;
4.Cell expansion conditions: casCellsBusy no storage capacity is false; the threads compete for resources; the number of cell does not exceed the number of CPU cores.
We look at an example, with LongAdder declare a value, so this value plus 10000 * 10 times, 10 is the number of threads:
public class ThreadLongAdder the implements the Runnable { // passed to a method of thread parameters static LongAdder count = new new LongAdder (); / ** * threaded tasks, the count value of the adding 10000 * 10 times * / public void RUN () { the System. Out.println ( "Get the current thread count value:" + count); for ( int I = 0; I <10000; I ++ ) { Long NUM = 1L ; count.add (NUM); } } public static voidmain (String [] args) throws InterruptedException { // create a multi-threaded environment, threads 10 created here the Thread [] = Thread new new the Thread [10 ]; // multithreaded adding threads not created task for ( int I = 0; I <10; I ++ ) { thread [I] = new new the thread ( new new ThreadLongAdder ()); } // start each thread task for ( int I = 0; I <10; I ++ ) { thread [I]. start (); } // action join method is to block the main thread, to prevent yet calculated, is started to output the count value for ( int0 = I; I <10; I ++ ) { Thread [I] .join (); } System.out.println ( "count calculation result is:" + count); } }
The results are: