Recently saw a multi-threaded interview problem, there are three threads to print a, B, C, please use multi-threaded programming, on the screen to cycle the printing of 10 times abcabc ...
To see this topic, the first thought is that the solution is to define an integer class object, initialized to 0, shared by 3 threads, if the integer object is equal to 0 after the remainder of 3, then print a, plus 1 operations, if the integer object 3 is equal to 1, then print B, Add 1 at the same time, if the integer object is equal to 1 after 3, print C and exit the thread if the loop prints 10 times.
/** * Threethread * 3 thread Test */public class Threethread {public static void main (string[] args) throws Interruptedexcept Ion {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 = = ten) {break; } else {Thread.yield (); try {sleep (10); } catch (Interruptedexception e) {e.printstacktrace (); } } } }}
The result of running the program is as follows:
Only a thread was found to have "a" printed, and no B threads and C threads were found to print the string: (. Does a thread change the value of an integer object, and B and C threads do not "see" the updated value? As a result, the add code in the while loop of the run method of the thread class is as follows:
while (true) { System.out.println (Thread.CurrentThread (). GetName () + "" + gData); Synchronized (gData) { if (gData% 3 = = N) { System.out.print (info + ""); gdata++; i++; } } ...}
The result of running the program is as follows:
It is shown from the running result that a, B, and C threads have an integer class variable at the beginning, and the initial value is 0. When a thread changes the integer class variable to 1 o'clock, but the value of the integer class variable in the B and C threads is still 0, the result will certainly not print out abcabc ....
By reading the integer class source, it is known that the variable type that holds the int value in the integer class is final:
/** * The value of the {@code Integer}. * * @serial */private final int value;
That is, each time the value of an integer class object is updated, a new integer object is created. The Run program results only print "a", indicating that the first A, B, and C threads all have the same integer class variable, and the initial value is 0, but when a thread updates the values of the integer object, the integer object in the a thread and the B/ The integer object in the C thread is no longer the same object.
In order to be able to print out the ABCABC string correctly, 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 Interruptedexcept Ion {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 = = ten) {break; } else {Thread.yield (); try {sleep (10); } catch (Interruptedexception e) {e.printstacktrace (); } } } }}
The second type of print Abcabc ... The solution to the string is to use the Wait/notify function, the sample code is as follows:
/** * ThreeThread2 * Three threads output a B C sequentially, using thread synchronization mode */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, "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.notify (); } try {prev.wait (); } catch (Interruptedexception e) {e.printstacktrace (); } } } }}
By a multi-threaded shared integer class variable problem caused by ...