简体   繁体   English

为什么 ReentrantLock signal() 不起作用?

[英]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.代码不会继续执行,因为它处于死锁状态。

  1. Student executes the 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 )线程,直到一个信号。
  2. Assistant executes the ask method on the Professor object. Assistant 对 Professor 对象执行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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM