Thread safety: Why does the num++ operation also have problems?

Source: Internet
Author: User

Thread security can be very complex, and in the absence of sufficient synchronization, the order in which operations are performed in multiple threads is unpredictable and can even produce strange results (unexpected). The plus method of the Tools tool class below will add one to the count, and for convenience, NUM and plus () are static:

 Public class Tools {    privatestaticint num = 0;     Public   Static int Plus () {        num++        ; return num;    }}

Let's write a task that calls the plus () method and outputs the count:

 Public class Implements Runnable {    @Override    publicvoid  run () {        int num =  Tools.plus ();        SYSTEM.OUT.PRINTLN (num);    }}

Finally create 10 threads to drive the task:

 Public class Main {    publicstaticvoid  main (string[] args) {        for ( int i = 0; I < 10; i++) {            new Thread (new  Task ()). Start ();     }}

Output:

24315678910

Everything looks normal, and 10 threads execute concurrently, resulting in a 0 cumulative 10-time result. We changed 10 times to 10,000 times:

 Public class Main {    publicstaticvoid  main (string[] args) {        for ( int i = 0; I < 10000; i++) {            new Thread (new  Task ()). Start ();     }}

Output:

... 99949995999699979998

On my computer, this program only occasionally output 10000, why?

The problem is that if the timing is not right, then two threads will get the same value when calling the plus () method, num++ appears to be a single operation, but in fact contains three operations: reads NUM, adds num One, and writes the result to Num. Because the runtime may alternately perform operations between multiple threads, these threads may perform read operations at the same time so that they get the same value and add 1 to the result that the same value is returned in different thread invocations.

A thread: num=9→→→9+1=10→→→num=10B Thread: →→→→num=9→→→9+1=10→→→num=10

If you take this action in a different way, it will look clearer, Num plus one assigns a temp variable, tmp, sleeps one second, and finally assigns TMP to NUM:

 Public classTools {Private Static intnum = 0;  Public Static intPlus () {intTMP = num + 1; Try{Thread.Sleep (1000); } Catch(interruptedexception e) {e.printstacktrace (); } num=tmp; returnnum; }}

This time we start with two threads to see the problem:

 Public class Main {    publicstaticvoid  main (string[] args) {        for ( int i = 0; I < 2; i++) {            new Thread (new  Task ()). Start ();     }}

After starting the program, the console outputs after 1s:

11
A thread: num=0→→→0+1=1→→→num=1B Thread: →num=0→→→0+1=1→→→num=1

The above example is a common concurrency security problem, called a race condition (Race Condition), in a multithreaded environment, whether plus () returns a unique value, depending on how the runtime alternates between operations on the thread, which is not what we want to see.

Because multiple threads share the same memory address space and are running concurrently, they may be able to access or modify the variables that other threads are using, and the thread can get an error due to unpredictable data changes. To make the behavior of multithreaded procedures predictable, access to shared variables must be coordinated so that there is no interference between threads. Fortunately, Java provides a variety of synchronization mechanisms to coordinate such access.

Modify the plus () to a synchronous method, and at the same time only one thread can enter the method to fix the error:

 Public classTools {Private Static intnum = 0;  Public synchronized Static intPlus () {intTMP = num + 1; Try{Thread.Sleep (1000); } Catch(interruptedexception e) {e.printstacktrace (); } num=tmp; returnnum; }}

Console output:

12

If you change the plus () method to num++ and drive 10,000 threads to execute, you can also ensure that you can output to 10000 each time.

In addition to security, multi-threaded threads can also have active problems (deadlocks, etc.), performance issues (context switching, etc.), which we will follow in detail.

  

Thread Safety: Why does the num++ operation also go wrong?

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.