-
Bug
-
Resolution: Not an Issue
-
P4
-
None
-
8, 11, 17, 18, 19
-
x86_64
-
windows_10
A DESCRIPTION OF THE PROBLEM :
hi team,
I have a question that signalAll function just transfer nodes that exists in the condition queue to CLH queue. However I found that AQS depeneds on unparkSuccessor to wake up thread one by one.
So , is there a puzzle or misunderstanding to learn that signalAll used to wake up all threads in condition queue.
We usually use Object.notifyAll compared to AQS.signalAll . Most of us think that signalAll will do two things:
1. transfer nodes from condition queue to CLH.
2. wake up those threads corresponded to nodes.
However , I just found one done. Because signalAll use transferForSignal op one by one.
Maybe I lose something or misunderstand signalAll.
Sincerely look forward to receiving else from you.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.Setup one breakpoint on System.out.println line in Thread3 run function.
2.Debug Application
3.Use jstack or [get thread dump] in idea's Debug pannel
4.You will find Thead1, Main, Thread2 are all waiting status.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
After completing signalAll() , thread1 and thread2 are Runnable status.
ACTUAL -
thread1 and thread2 are waiting status.
---------- BEGIN SOURCE ----------
Main Class:
public class Application {
private static ReentrantLock _lock = new ReentrantLock();
private static Condition _cond = _lock.newCondition();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new Thread1(_lock,_cond),"thread1");
Thread thread2 = new Thread(new Thread2(_lock,_cond),"thread2");
Thread thread3 = new Thread(new Thread3(_lock,_cond),"thread3");
thread1.start();
thread2.start();
thread3.start();
thread1.join();
thread2.join();
thread3.join();
System.out.println("main end");
}
}
public class Thread1 implements Runnable{
private ReentrantLock _lock;
private Condition _cond;
public Thread1(ReentrantLock _lock, Condition _cond) {
this._lock = _lock;
this._cond = _cond;
}
@Override
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(String.format("%s----,启动",threadName));
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
_lock.lock();
System.out.println(String.format("%s----,wait前",threadName));
try {
_cond.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(String.format("%s----,wait后,time:%d",threadName,System.currentTimeMillis()));
_lock.unlock();
}
}
public class Thread2 implements Runnable{
private ReentrantLock _lock;
private Condition _cond;
public Thread2(ReentrantLock _lock, Condition _cond) {
this._lock = _lock;
this._cond = _cond;
}
@Override
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(String.format("%s----,启动",threadName));
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2));
_lock.lock();
System.out.println(String.format("%s----,wait前",threadName));
try {
_cond.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(String.format("%s----,wait后,time:%d",threadName,System.currentTimeMillis()));
_lock.unlock();
}
}
public class Thread3 implements Runnable{
private ReentrantLock _lock;
private Condition _cond;
public Thread3(ReentrantLock _lock, Condition _cond) {
this._lock = _lock;
this._cond = _cond;
}
@Override
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(String.format("%s----,启动",threadName));
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(3));
_lock.lock();
System.out.println(String.format("%s----,signal前",threadName));
_cond.signalAll();
System.out.println(String.format("%s----,signal后",threadName));
_lock.unlock();
}
}
---------- END SOURCE ----------
hi team,
I have a question that signalAll function just transfer nodes that exists in the condition queue to CLH queue. However I found that AQS depeneds on unparkSuccessor to wake up thread one by one.
So , is there a puzzle or misunderstanding to learn that signalAll used to wake up all threads in condition queue.
We usually use Object.notifyAll compared to AQS.signalAll . Most of us think that signalAll will do two things:
1. transfer nodes from condition queue to CLH.
2. wake up those threads corresponded to nodes.
However , I just found one done. Because signalAll use transferForSignal op one by one.
Maybe I lose something or misunderstand signalAll.
Sincerely look forward to receiving else from you.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.Setup one breakpoint on System.out.println line in Thread3 run function.
2.Debug Application
3.Use jstack or [get thread dump] in idea's Debug pannel
4.You will find Thead1, Main, Thread2 are all waiting status.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
After completing signalAll() , thread1 and thread2 are Runnable status.
ACTUAL -
thread1 and thread2 are waiting status.
---------- BEGIN SOURCE ----------
Main Class:
public class Application {
private static ReentrantLock _lock = new ReentrantLock();
private static Condition _cond = _lock.newCondition();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new Thread1(_lock,_cond),"thread1");
Thread thread2 = new Thread(new Thread2(_lock,_cond),"thread2");
Thread thread3 = new Thread(new Thread3(_lock,_cond),"thread3");
thread1.start();
thread2.start();
thread3.start();
thread1.join();
thread2.join();
thread3.join();
System.out.println("main end");
}
}
public class Thread1 implements Runnable{
private ReentrantLock _lock;
private Condition _cond;
public Thread1(ReentrantLock _lock, Condition _cond) {
this._lock = _lock;
this._cond = _cond;
}
@Override
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(String.format("%s----,启动",threadName));
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
_lock.lock();
System.out.println(String.format("%s----,wait前",threadName));
try {
_cond.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(String.format("%s----,wait后,time:%d",threadName,System.currentTimeMillis()));
_lock.unlock();
}
}
public class Thread2 implements Runnable{
private ReentrantLock _lock;
private Condition _cond;
public Thread2(ReentrantLock _lock, Condition _cond) {
this._lock = _lock;
this._cond = _cond;
}
@Override
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(String.format("%s----,启动",threadName));
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2));
_lock.lock();
System.out.println(String.format("%s----,wait前",threadName));
try {
_cond.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(String.format("%s----,wait后,time:%d",threadName,System.currentTimeMillis()));
_lock.unlock();
}
}
public class Thread3 implements Runnable{
private ReentrantLock _lock;
private Condition _cond;
public Thread3(ReentrantLock _lock, Condition _cond) {
this._lock = _lock;
this._cond = _cond;
}
@Override
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(String.format("%s----,启动",threadName));
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(3));
_lock.lock();
System.out.println(String.format("%s----,signal前",threadName));
_cond.signalAll();
System.out.println(String.format("%s----,signal后",threadName));
_lock.unlock();
}
}
---------- END SOURCE ----------