This error is caused by a multi-threaded Integer shared variable.

Source: Internet
Author: User

This error is caused by a multi-threaded Integer shared variable.

I recently saw a multi-thread interview question,Three threads Print A, B, and C respectively. use multi-threaded programming to print 10 ABCABC... 

When we see this question, we first think of a solution that defines an Integer Class Object, initialized to 0, which is shared by three threads. If the Integer object is equal to 0 after the remainder of 3, print A and Add 1 at the same time. If the Integer object is equal to 1 after 3, print B and Add 1 at the same time. If the Integer object is equal to 1 after 3, print C. If the loop is printed 10 times, exit the thread.

/*** ThreeThread * 3 thread test */public class ThreeThread {public static void main (String [] args) throws InterruptedException {Integer gData = 0; thread thread1 = new MyTask (gData, 0, "A"); Thread thread2 = new MyTask (gData, 1, "B"); Thread thread3 = new MyTask (gData, 2, "C"); thread1.start (); thread2.start (); thread3.start (); thread1.join (); thread2.join (); thread3.join () ;}} class MyTask extends Thread {private Integer gData; private int n; private String info; public MyTask (Integer gData, int n, String info) {super ("thread" + info); this. gData = gData; this. n = n; this.info = info;} public void run () {int I = 0; while (true) {synchronized (gData) {if (gData % 3 = n) {System. out. print (info + ""); gData ++; I ++ ;}}if (I = 10) {break ;}else {Thread. yield (); try {sleep (10);} catch (InterruptedException e) {e. printStackTrace ();}}}}}

The running result is as follows:

It is found that only thread A prints "A", and thread B and thread C do not print strings :(. Does thread A change the value of the Integer object, but thread B and thread C do not "see" the updated value? Therefore, add the following code to the while loop of the run method of the thread class:

while (true) {    System.out.println(Thread.currentThread().getName() + " " + gData);    synchronized (gData) {        if (gData % 3 == n) {            System.out.print(info + " ");            gData++;            i++;        }    }    ...}

The running result is as follows:

According to the running results, the first threads A, B, and C all have Integer variables, and the initial value is 0. When thread A changes the Integer variable to 1, but the value of the Integer variable in thread B and thread C is still 0, the result will certainly not print ABCABC ....

By reading the source code of the Integer class, we can see that the variable type of the int value stored in the Integer class is final:

/** * The value of the {@code Integer}. * * @serial */private final int value;

That is to say, each update of the value of an Integer object creates a new Integer object. Only "A" is printed in the running program, indicating that at the beginning A, B, and C threads all have the same Integer variable, and the initial value is 0, however, after thread A updates the value of the Integer object, the Integer object in thread A is not the same as the Integer object in thread B/C.

To print the ABCABC string properly, you can change the Integer object type to AtomicInteger. The Code is as follows:

/*** ThreeThread * 3 thread test */public class ThreeThread {public static void main (String [] args) throws InterruptedException {AtomicInteger gData = new AtomicInteger (0 ); thread thread1 = new MyTask (gData, 0, "A"); Thread thread2 = new MyTask (gData, 1, "B"); Thread thread3 = new MyTask (gData, 2, "C"); thread1.start (); thread2.start (); thread3.start (); thread1.join (); thread2.join (); thread3.join () ;}} class MyTask extends Thread {private AtomicInteger gData; private int n; private String info; public MyTask (AtomicInteger gData, int n, String info) {super ("thread" + info); this. gData = gData; this. n = n; this.info = info;} public void run () {int I = 0; while (true) {synchronized (gData) {if (gData. get () % 3 = n) {System. out. print (info + ""); gData. incrementAndGet (); I ++ ;}} if (I == 10) {break;} else {Thread. yield (); try {sleep (10);} catch (InterruptedException e) {e. printStackTrace ();}}}}}

 

The second method to print the ABCABC... string is to use the wait/notify function. The sample code is as follows:

/*** ThreeThread2 * three threads Output a B C in sequence and use the thread synchronization method */public class ThreeThread2 {public static void main (String [] args) throws InterruptedException {Object A = new Object (); Object B = new Object (); Object C = new Object (); MyThread myThread1 = new MyThread (C,, "A"); MyThread myThread2 = new MyThread (A, B, "B"); MyThread myThread3 = new MyThread (B, C, "C"); myThread1.start (); thread. sleep (10); myThread2.start (); Thread. sleep (10); myThread3.start (); try {myThread1.join (); myThread2.join (); myThread3.join ();} catch (InterruptedException e) {e. printStackTrace () ;}} class MyThread extends Thread {private Object prev; private Object curr; private String info; public MyThread (Object prev, Object curr, String info) {this. prev = prev; this. curr = curr; this.info = info;} public void run () {int cnt = 10; while (cnt --> 0) {synchronized (prev) {synchronized (curr) {System. out. print (info + ""); curr. optional Y ();} try {prev. wait ();} catch (InterruptedException e) {e. printStackTrace ();}}}}}

 

Related Article

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.