AtomicInteger package under the Java Automic

Thank these two bloggers articles, articles from:

https://www.cnblogs.com/chenpi/p/5375805.html

https://blog.csdn.net/fanrenxiang/article/details/80623884

 

Version: dk1.5 provides, java.util.concurrent.atomic package

Action: programmers to in a multithreaded environment, the lock-atomic operations

Bottom: the underlying atomic variables using atomic instructions provided by the processor, but different atomic instructions CPU architecture may provide different, there may need some form of internal locking, so this method can not absolutely guarantee the thread is not blocked

Inner core: Atomic inside the bag using synchronized implementation is not simple, but a more efficient way to CAS (compare and swap) + volatile and native methods (synchronous work more to the hardware), thus avoiding the synchronized high overhead, greatly enhance the efficiency

About CAS:

compare and swap, compare and replacement techniques, the expected value and the current value of the comparison variable (Compare), with a new replacement if it is equal (the swap) the current value of the variable, or is not operating;

Modern CPU has been widely supported CAS instruction, if not support, then the JVM will use a spin lock, and mutex the same, both must first acquire the lock to access shared resources, but mutex causes the thread goes to sleep, and since spin lock would have been to wait until the cycle to acquire the lock;

In addition, one thing should be noted that the ABA problem CAS operation, the time will soon expected value to be compared with the current value of the variable, even if there is no guarantee equal variable has not been modified, because the variable may become B from A back to A again to resolve this problem, you can increase the version number to a variable, the variable each time a modified version number increment, time comparison, while comparing the values ​​of variables and version number can be;

 

Atomic package substantially atomically update type:

1.AtomicBoolean: atomic update Boolean type.

2.AtomicInteger: atomic updates integer.

3.AtomicLong: atomic update long integer.

To AtomicInteger for example, source code:

Package Concurrency;
 Import java.util.concurrent.atomic.AtomicInteger; 

public  class AtomicIntegerTest { 

    static of AtomicInteger AI = new new of AtomicInteger (. 1 ); 

    public  static  void main (String [] args) {
         // corresponds i ++, returns the old value see the method name, we know that first and then get increment 
        System.out.println (ai.getAndIncrement ()); 
        System.out.println (ai.get ()); 
        // first increment, then get 
        System.out. the println (ai.incrementAndGet ()); 
        System.out.println (ai.get ()); 
        // add a specified value, to add, then GET 
        System.out.println (ai.addAndGet (. 5 ));
        System.out.println (ai.get ()); 
        // add a specified value, to get, then SET 
        System.out.println (ai.getAndSet (. 5 )); 
        System.out.println (ai.get () ); 
    } 

}

Why do I need AtomicInteger atomic operations class?

For Java in arithmetic operations, such as increment or decrement, if no additional synchronization in multi-threaded environment is not thread-safe. num ++ resolved to num = num + 1, obviously, do not have this atomic operation, concurrency problems when bound to the shared variable multithreaded. Test code is as follows:

public class AtomicIntegerTest {
 
    private static final int THREADS_CONUT = 20;
    public static int count = 0;
 
    public static void increase() {
        count++;
    }
 
    public static void main(String[] args) {
        Thread[] threads = new Thread[THREADS_CONUT];
        for (int i = 0; i < THREADS_CONUT; i++) {
            threads[i] = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000; i++) {
                        increase();
                    }
                }
            });
            threads[i].start();
        }
 
        while (Thread.activeCount() > 1) {
            Thread.yield();
        }
        System.out.println(count);
    }
}

Here running 20 threads, each of the count variables 1000 this increment operator, if the code above the normal concurrent, then the end result should be 20,000 fishes, but the actual result was found that the results of each run are are not the same, it is a number less than 20,000.

 

Then AtomicInteger:

import java.util.concurrent.atomic.AtomicInteger;
 
public class AtomicIntegerTest {
 
    private static final int THREADS_CONUT = 20;
    public static AtomicInteger count = new AtomicInteger(0);
 
    public static void increase() {
        count.incrementAndGet();
    }
 
    public static void main(String[] args) {
        Thread[] threads = new Thread[THREADS_CONUT];
        for (int i = 0; i < THREADS_CONUT; i++) {
            threads[i] = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000; i++) {
                        increase();
                    }
                }
            });
            threads[i].start();
        }
 
        while (Thread.activeCount() > 1) {
            Thread.yield();
        }
        System.out.println(count);
    }
}

The results output every 20,000, the program outputs the correct result, thanks atomic AtomicInteger.incrementAndGet () method.

 

Note: Atomic package provides three basic types of atomic update, the remaining basic types of Java there char, float and double, and so that updates and can refer to current thinking AtomicBoolean, AtomicBoolean is converted into the integer boolean recalled CAS compareAndSwapInt be achieved, and similar short byte may be transferred to an integer, float, and double may be utilized Float.floatToIntBits, Double.doubleToLongBits converted to long int and the corresponding shaping process;

 

In the low degree of competition, provide greater scalability atoms class; in a competitive high strength, the lock can better help us to avoid competition. (From "real concurrent programming")

Therefore, we must, as the case may be, if small-scale competition for resources, smaller particle size control, the use of atomic analogy better use of locks, can improve the efficiency and performance

 

Guess you like

Origin www.cnblogs.com/hetaoyuan/p/11401728.html