[英]why ReentrantLock signal() isn't working?
Although i waked the Thread by signal(), Thread still in waiting pool(i think) and it works only once.虽然我通过信号()唤醒了线程,但线程仍在等待池中(我认为)它只工作一次。
while(true){
professor.ask();
}
because of the code i thought it shoud repeat ask again and again由于代码,我认为它应该一遍又一遍地重复询问
i have two Threads "Student","Jogyo" if Student asks then, Jogyo get signal().vice versa.我有两个线程“学生”,“Jogyo”,如果学生问,Jogyo 得到信号()。反之亦然。
below is my code下面是我的代码
public class LockEx1 {
public static void main(String[] args) {
Professor professor = new Professor();
new Thread(new Student(professor), "student kim").start();
new Thread(new JoGyo(professor), "assistant choi").start();
try{Thread.sleep(20000);}catch (InterruptedException e){}
System.exit(0);
}
}
class Student implements Runnable {
Professor professor; // shared resource
Student(Professor professor) {
this.professor = professor;
}
@Override
public void run() {
while (true) {
professor.ask();
}
}
}
class JoGyo implements Runnable {
Professor professor; // shared resource
JoGyo(Professor professor) {
this.professor = professor;
}
@Override
public void run() {
while (true) {
try {Thread.sleep(100);} catch (InterruptedException e) {}//catch
professor.ask();
}
}
}
class Professor {
private final ReentrantLock lock = new ReentrantLock();
Condition forJoGyo = lock.newCondition();
Condition forStudent = lock.newCondition();
// 교수님께 질문하기
public void ask() {
lock.lock(); // sync -- start
String name = Thread.currentThread().getName();
System.out.println(name + ": have a question. professor!");
for (int i = 0; i < 5; i++) {
try {Thread.sleep(500);} catch (InterruptedException e) {}
System.out.println("professor: " + "explaining.." + i + " " + name + " listening.." );
}//for
System.out.println(name + ": thanks professor");
if (name.contains("assistant")) {
try{forJoGyo.await();}catch (InterruptedException e){} // 조교 재우기
forStudent.signal(); // 학생 깨우기
}
else if (name.contains("student")) {
try{forStudent.await();}catch (InterruptedException e){} // 학생 재우기
forJoGyo.signal(); // 조교 깨우기
}
lock.unlock(); // sync -- end
}//ask
}
as you see..it works(ask to professor each only onces at all) only once.如你所见..它只工作一次(每个人只问一次教授)。 is this because signal() is not working?
这是因为 signal() 不起作用吗? why it doesn't repeat asking to professor..
为什么它不重复问教授..
The code does not execute any further because it is in a deadlock state.代码不会继续执行,因为它处于死锁状态。
ask
method on the Professor object.ask
方法。 The printing code is executed and the lock condition forStudent
is starting to block ( await
) the thread until a signal.forStudent
的锁定条件开始阻塞( await
)线程,直到一个信号。ask
method on the Professor object. ask
方法。 The printing code is executed an the lock condition foJoGyo
is starting to block ( await
) the thread until an await signal.foJoGyo
开始阻塞 ( await
) 线程时执行,直到出现 await 信号。 Both threads are now waiting for a signal from the other one.两个线程现在都在等待来自另一个线程的信号。 None can reach the signal code, so the threads are locked forever (deadlock) - in this case until the sleep time before returning from the
main
method is reached.没有人可以到达信号代码,因此线程被永远锁定(死锁) - 在这种情况下,直到达到从
main
方法返回之前的睡眠时间。
The signal unlocking the other thread should be emitted before starting the waiting for the signal from the other thread, otherwise both threads will wait forever.解锁另一个线程的信号应该在开始等待来自另一个线程的信号之前发出,否则两个线程将永远等待。
if (name.contains("assistant")) {
forStudent.signal();
try {
forJoGyo.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else if (name.contains("student")) {
forJoGyo.signal();
try {
forStudent.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Result:结果:
student kim: have a question. professor!
professor: explaining..0 student kim listening..
professor: explaining..1 student kim listening..
professor: explaining..2 student kim listening..
professor: explaining..3 student kim listening..
professor: explaining..4 student kim listening..
student kim: thanks professor
assistant choi: have a question. professor!
professor: explaining..0 assistant choi listening..
professor: explaining..1 assistant choi listening..
professor: explaining..2 assistant choi listening..
professor: explaining..3 assistant choi listening..
professor: explaining..4 assistant choi listening..
assistant choi: thanks professor
student kim: have a question. professor!
professor: explaining..0 student kim listening..
professor: explaining..1 student kim listening..
professor: explaining..2 student kim listening..
professor: explaining..3 student kim listening..
professor: explaining..4 student kim listening..
student kim: thanks professor
assistant choi: have a question. professor!
professor: explaining..0 assistant choi listening..
professor: explaining..1 assistant choi listening..
professor: explaining..2 assistant choi listening..
professor: explaining..3 assistant choi listening..
professor: explaining..4 assistant choi listening..
assistant choi: thanks professor
student kim: have a question. professor!
professor: explaining..0 student kim listening..
professor: explaining..1 student kim listening..
professor: explaining..2 student kim listening..
professor: explaining..3 student kim listening..
professor: explaining..4 student kim listening..
student kim: thanks professor
assistant choi: have a question. professor!
professor: explaining..0 assistant choi listening..
professor: explaining..1 assistant choi listening..
professor: explaining..2 assistant choi listening..
professor: explaining..3 assistant choi listening..
professor: explaining..4 assistant choi listening..
assistant choi: thanks professor
student kim: have a question. professor!
professor: explaining..0 student kim listening..
professor: explaining..1 student kim listening..
professor: explaining..2 student kim listening..
professor: explaining..3 student kim listening..
professor: explaining..4 student kim listening..
student kim: thanks professor
Important sidenote: unlock
call should be placed inside a finally
block with try
block containing the code after lock
to avoid a situation when the lock is never unlocked in case of an exception or an early return .重要的旁注:
unlock
调用应该放在finally
块中, try
块包含lock
之后的代码,以避免在异常或提前返回的情况下锁永远不会解锁的情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.