Article From:https://segmentfault.com/q/1010000012150958
Question:

The main function is to print AB using two threads.

Problems arise: when run () in PrintB is called, it is found through Debug mode debugging that it is first entered the loop body and then the condition is judged, resulting in the output of the data more than one time.

The source code is as follows:

    Thread sharing resources: Printer/ * * * * ** shared resources: printers* @author Tangxkun** * /Public class Printer {/ / maximum printfrequencyPrivate Final int MAX_COUNT = 5;//false indicates that the printer does not print A, and true indicates that the printer is printing A.Private Boolean prIntingA = false;Private int count = 0;Public synchronized void printA () {SystEm.out.println (count++);PrintingA = true;System.out.println ("A");NotifyAlL ();}Public synchronized void printB () {System.out.println (count++);PrintIngA = false;System.out.println ("B");NotifyAll ();}Public synchronized VoID aWaiting () throws InterruptedException{While (printingA = = true) {Wait ();}}Public synchronized void bWaiting () throws InterruptedException{While (prinTingA = = = false) {Wait ();}}Public int getCount () {ReturnCount;}Public void setCount (int count) {This.count = count;}Public intGetMAX_COUNT () {Return MAX_COUNT;}}

Print A’s thread task:

/**
 * Print the threads of A* @author Tangxkun** * /Public class PrintA implements Runnable{Private Printer prinTer;Public PrintA (Printer printer) {Super ();This.printer = printer;}@OverridePublic void run () {While (printer.getCount () < printer.getMAX_COUNT).)) {Printer.printA ();Try {Printer.aWaiting ();} catch (InterruptedException E) {/ / TODO Auto-generated catch blockE.printStackTrace ();}}}}

Print B’s thread task:

/**
 * Print the threads of B* @author Tangxkun** * /Public class PrintB implements Runnable{Private Printer prinTer;Public PrintB (Printer printer) {Super ();This.printer = printer;}@OverridePublic void run () {While (printer.getCount () < printer.getMAX_COUNT).)) {Try {Printer.bWaiting ();} catch (InterruptedExceptionE) {/ / TODO Auto-generated catch blockE.printStackTrace ();}Printer.printB ();}}}

Test code:

/**
 * Test code* @author Tangxkun** * /Public class Test {Public static void main (String[] args) {Printer printer = new Printer ();PrintA printA = new PrintA (printer);PrintB printB = new PrintB (printer);Thread threadA = new Thread (printA, "A");Thread threadB = new Thread (printB, "B");ThreadA.start ();ThreadB.starT ();}}

When MAX_COUNT=5 is set, the output results are:

When MAX_COUNT=6 is set, the output results are:

When MAX_COUNT=7 is set, the output results are:

After burning your brain for a long time, you still haven’t found any clues. So please come and ask your great gods!

Answer 0:

The reason is finally found, is that he did not understand the thread hanging concept. When the thread B is first executed, the while condition determines entry, then hangs, and does not execute printer.printB (), when thread A wakes thread B, thread B from the code where the thread is hanging.Continue to execute (execute printer.printB (), perform the previously suspended task) rather than restart run (), that is to say, no further while condition judgment is done, and then the while loop is finally reentered.

Leave a Reply

Your email address will not be published. Required fields are marked *