Thread-safe AtomicLong usage

atomiclong can be understood as a synchronized long.

public class Counter {  
    private static long counter = 0;  
    public static long addOne(){  
        return ++counter;  
    }  
} 

This class will have problems in a multi-threaded environment. If multiple threads are opened to use this counting class, it will behave "unstable"

    public static void main(String[] args) {  
        for(int i=0;i<100;i++){  
            Thread thread = new Thread(){  
                @Override  
                public void run() {  
                    try {  
                        Thread.sleep(100);  
                        if(Counter.addOne() == 100){  
                            System.out.println("counter = 100");  
                        }  
                    } catch (InterruptedException e) {  
                        e.printStackTrace();  
                    }  
                }  
            };  
            thread.start();  
        }  
    }  

The program will open 100 threads, and each thread will increase the counter by one. Then there should be a thread to get the value of counter = 100, but the actual running situation is that it can't get 100 in most data cases, and can get 100 in a few cases.

Because the Counter class does not guarantee thread safety when the addOne() method is called, that is, it is not run at the atomic level, but in multiple steps.

For example: Thread 1 first gets the counter value, such as 10, and then it is ready to add 1. At this time, the CPU is occupied by thread 2. It gets the counter value as 10, and then adds 1 to get 11. At this time, thread 1 gets the CPU resource again, continues its steps, adds 1 to 11, and then also gets 11. This is the problem.

So how to solve it? JDK provides the implementation of some thread-safe basic data types in the concurrent package. For example, the class of the concurrent package corresponding to the Long type is AtomicLong.

Now modify the code:

    import java.util.concurrent.atomic.AtomicLong;  


    public class Counter {  
        private static AtomicLong counter = new AtomicLong(0);  


        public static long addOne() {  
            return counter.incrementAndGet();  
        }  
    }  

After running it many times, the result is that it can output counter = 100.

So in a multithreaded environment, you can simply use AtomicXXX to make your code thread-safe.

Reprinted from: http://blog.csdn.net/yaqingwa/article/details/17737771

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325762310&siteId=291194637