Home > Back-end >  With LockSupport Leetcode1116 concurrency problem, to ask what went wrong
With LockSupport Leetcode1116 concurrency problem, to ask what went wrong

Time:09-20

The original link: https://leetcode-cn.com/problems/print-zero-even-odd/

Problem of :
Screwing for 2 days, do not understand, chicken son, is probably in the hundreds of times after the operation will have obvious synchronization problems lead to the result error, sometimes puzzling block , don't know what do the old man give, change the solution doesn't have to ~

The solution to I :
The main method to test the output redirection, then access to print the value judgment, inconsistent and expectations are break, also rely on a package similar to Consumer functions into a Runnable and try to catch exceptions interface, the trouble can write their own tests,

 public class Solution1116 {

The static CountDownLatch CDL=new CountDownLatch (3);

Public static void main (String [] args) {
ZeroEvenOdd zeo=new ZeroEvenOdd (9);

//redirect the output stream related operations
ByteArrayOutputStream baos=new ByteArrayOutputStream ();
PrintStream ps=new PrintStream (baos);
PrintStream old=System. Out;
System. SetOut (ps);

//initialize three Runnable threads and
IntConsumer IC=System. Out: : print;
The ExecutorService es=Executors. NewFixedThreadPool (3);
A Runnable r0=ConsumerCatch. RunnableWrap (zeo: : zero, IC);//need the support of ConsumerCatch interface
A Runnable r1=ConsumerCatch. RunnableWrap (zeo: : odd, IC);
A Runnable r2=ConsumerCatch. RunnableWrap (zeo: : even, IC);
While (true) {
Es. Submit (r0);
Es. Submit (r1);
Es. Submit (r2);
Try {
CDL. Await ();//blocking the main thread
{} catch InterruptedException (e)
e.printStackTrace();
}

//print and compare the results
Ps. Flush ();
System. SetOut (old);
String s=baos. ToString ();
System. The out. Println (s);
if (! S.e quals (" 010203040506070809 ")) {
break;
}

//reset all
Baos. Reset ();
CDL=new CountDownLatch (3);
Zeo. Reset ();
System. SetOut (ps);
}
}

Private static class ZeroEvenOdd {

Private int n;
Private volatile int current=1;//deprecated
Private AtomicInteger ai=new AtomicInteger (1);

Private volatile Thread t0=null;
Private volatile Thread t1=null;
Private volatile Thread t2=null;

Public ZeroEvenOdd (int n) {
This. N=n;
}

//test, used to make the object back to the initial state
Public void reset () {
Ai. Set (1);
T0=null;
T1=null;
T2=null;
}

//printNumber. Accept (x) outputs "x", where x is an integer.
Public void zero (IntConsumer printNumber) throws InterruptedException {
T0=Thread. CurrentThread ();
for (int i=0; i PrintNumber. Accept (0);
While (t1==null | | t2==null) {}//spin that initialization + memory barrier
If ((ai. The get () & amp; 1)==1)
LockSupport. Unpark (t1);
The else
LockSupport. Unpark (t2);
if (i !=n - 1)
LockSupport. Park ();
}
Solution1116. CDL. CountDown ();//test, only to the main thread release
}

Public void even (IntConsumer printNumber) throws InterruptedException {
T2=Thread. CurrentThread ();
for (int i=0; i LockSupport. Park ();
PrintNumber. Accept (ai) getAndIncrement ());
LockSupport. Unpark (t0);
}
Solution1116. CDL. CountDown ();//test, only to the main thread release
}

Public void odd (IntConsumer printNumber) throws InterruptedException {
T1=Thread. CurrentThread ();
for (int i=0; i LockSupport. Park ();
PrintNumber. Accept (ai) getAndIncrement ());
LockSupport. Unpark (t0);
}
Solution1116. CDL. CountDown ();//test, only to the main thread release
}
}
}


main method relies on the interface of :
Mainly to write less the try catch, on the whole a
 @ FunctionalInterface 
Public interface ConsumerCatch {

The static & lt; T> A Runnable runnableWrap (ConsumerCatch Ct, T, T) {
Return () - & gt; {
Try {
Ct. Accept (t);
} the catch (Exception e) {
e.printStackTrace();
}
};
}

The static & lt; T> Thread threadWrap (ConsumerCatch Ct, T, T) {
Return the new Thread (() - & gt; {
Try {
Ct. Accept (t);
} the catch (Exception e) {
e.printStackTrace();
}
});
}

Void the accept (T T) throws the Exception;
}

CodePudding user response:

Running like this N times to problems in multi-threaded programs, you will be how the debug, I say very short of the methodology, know the problem and I can also into any longer,

CodePudding user response:

Ok, I know where the problem is,
 
if (i !=n - 1)
LockSupport. Park ();

Problem at zero ways this if judgment, it results in each run park and unpark number is different, and each will issue a permit to more than one thread, namely the immunity of the next park, remove it's no problem,

As to why use fixed thread pool, the error will run up to 5000 times to appear, and the newly created thread this error every time as long as 2 times, now I also can't explain, need to know to whom the permit, if go with thread, so every time a new thread must not before the immunity, it is counterintuitive,
  • Related