Multithreading Concurrency issues

Source: Internet
Author: User
Tags modifier visibility volatile

0. Foreword

Reprint please indicate the source: http://blog.csdn.net/seu_calvin/article/details/52370068

The interview is likely to encounter the problem: the use of volatile modifier int variable i, multiple threads at the same time i++ operations, so that thread security can be implemented. When it comes to thread safety and thread synchronization, we often think of two keywords: volatile and synchronized, so what's the difference between the two?

1. Volatile modified variables are visible

Volatile is a variable modifier whose modified variable has visibility.

Visibility means that once a thread modifies the volatile-modified variable, it guarantees that the modified value is immediately updated to main memory, and that the modified value is immediately available when other threads need to read it.

In Java, in order to speed up the operation of the program, the operation of some variables is usually done on the thread's register or CPU cache, before it is synchronized to main memory, and the variable with the volatile modifier is directly read and write main memory.

For examples please look at the 3.1 below to help understand.


2. Volatile prohibit order rearrangement

Volatile can be prevented from being ordered to rearrange.

Instruction rearrangement refers to the processor in order to improve the efficiency of the program, the input code may be optimized, it does not guarantee that the execution order of the individual statements in accordance with the order in the code, but it will ensure that the results of the final execution of the program and the sequence of code execution results are consistent. Instruction reordering does not affect the execution of individual threads, but it affects the correctness of concurrent execution of threads.

When a program performs a read or write operation to a volatile modifier variable, the previous operation must have been completed, and the result is visible to the subsequent operation, which must not have been done.

For examples please check below 3.2 to help understand.


3. Synchronized

Synchronized can be used as a piece of code or method to guarantee visibility and atomicity.

Visibility is demonstrated by synchronized or lock, which guarantees that only one thread acquires the lock at the same time and then executes the synchronization code, and refreshes the changes to main memory before releasing the lock.

Atomicity is manifested in: either does not execute, or carries out the end.

For examples please check below 3.3 to help understand.

2. Summary
(1) Thus we can see that volatile, though visible, does not guarantee atomicity.

(2) performance, the Synchronized keyword is to prevent multiple threads to execute a piece of code at the same time, will affect the efficiency of program execution, and volatile keyword in some cases performance is better than synchronized.

However, note that the volatile keyword cannot be substituted for the Synchronized keyword because the volatile keyword does not guarantee the atomic nature of the operation.

3. Examples of use scenarios for volatile and synchronized (combined with part 1th for understanding learning)

Examples of the use of 3.1 volatile

[java]  View Plain  copy class mythread extends thread {                   private volatile  boolean isstop = false;                public void run ()  {                while  (!isstop)  {                    system.out.println ("do something");                }           }           public void  Setstop ()  {               isstop  = true;           }             }    

When a thread executes run () We need to do something constantly in the threads, such as the while loop, and then how to stop the thread. If the thread does something that is not time-consuming, then just use a flag. If you need to exit, call Setstop (). The keyword volatile is used here, and the purpose of this keyword is to modify the value of the isstop so that it can be read immediately to the modified value in the while loop.

If the thread does things that are time-consuming, you can use the interrupt method to terminate the thread. If the child thread "sleeps" is interrupt, the child thread can catch to the interruptexpection exception, and then continue to execute after the exception is handled.

Examples of the use of 3.2 volatile [Java] view plain copy//thread 1:context = Loadcontext ();             Statement 1 Context initialization operation inited = true; Statement 2//thread 2:while (!inited) {sleep ()} dosomethingwithconfig (context);

Because of the command reordering, it is possible that statement 2 will execute before statement 1, which may cause the context to not be initialized, and thread 2 uses the uninitialized language to do the operation, causing the program to go wrong.

This is not a problem if you decorate the inited variable with the volatile keyword.

 

3.3  must use synchronized to not use volatile scene [java]  view plain  copy        public volatile int inc = 0;        public void increase ()  {            inc++;       }               public static void main (String[] args)  {            final test test = new test ();           for (int i=0;i<10;i++) {                new thread () {                    public void run ()  {                         for (int j=0;j<1000;j++)                             test.increase ();                    };                }.start ();            }                        while (Thread.activecount () >1)   // Ensure that all previous threads are finished                thread.yield ();            system.out.println (test.inc);        }  }  

The example uses the new 10 threads, respectively to call 1000 times increase () method, each run the result is inconsistent, is a number less than 10000. Self-augmentation is not atomic, and volatile is not guaranteed to be atomic. Back to the example at the beginning of the article, using the volatile modifier int variable i, multiple threads at the same time i++ operation. For example, there are two threads A and B to perform i++ operations on volatile modified I. The initial value of I is that when the 0,a thread executes the i++, it just reads the value 0 of I, switches to the B thread, and the B thread reads I by 0, and then switches to a thread to continue the i++ operation. I will be 1 after I finish, then switch to B thread, because I have read it before, so I continue to perform the i++ operation, the final result I is 1. The same can explain why each run results in a number less than 10000.
However, using synchronized to modify part of the code as follows ensures that only one thread acquires the lock at the same time and then executes the synchronization code. The result of the operation must be 10000.   [Java] View plain copy public int inc = 0;   Public synchronized void Increase () {inc++; }

This article collates the reference from:
Http://www.cnblogs.com/dolphin0520/p/3920373.html and Warmor's blog.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.