首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么ReentrantLock信号()不能工作?

为什么ReentrantLock信号()不能工作?
EN

Stack Overflow用户
提问于 2022-07-04 07:39:31
回答 1查看 34关注 0票数 0

虽然我通过信号()唤醒了线程,但是线程仍然在等待池中(我认为),它只工作了一次。

代码语言:javascript
复制
while(true){
professor.ask();
}

因为代码,我认为它应该重复一遍又一遍。

我有两个线程“学生”," Jogyo“,如果学生问的话,Jogyo得到信号().vice相反。

下面是我的代码

代码语言:javascript
复制
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
}

当你工作时,see..it只工作一次(每次只问教授一次)。这是因为信号()不起作用吗?为什么它不重复问教授..。

EN

回答 1

Stack Overflow用户

发布于 2022-07-04 13:52:55

代码不再执行,因为它处于死锁状态。

  1. 学生对“教授”对象执行ask方法。打印代码被执行,锁条件forStudent开始阻塞(await)线程直到信号。
  2. 助手对ask对象执行该方法。打印代码被执行,锁条件foJoGyo开始阻塞(await)线程,直到等待信号。

两个线程现在都在等待来自另一个线程的信号。没有人能够到达信号代码,因此线程被永久锁定(死锁)-在这种情况下,直到到达从main方法返回之前的睡眠时间。

在开始等待来自另一个线程的信号之前,应该发出释放另一个线程的信号,否则两个线程都将永远等待。

代码语言:javascript
复制
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();
    }
}

结果:

代码语言:javascript
复制
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

重要的sidenote:应该将unlock finally 调用放在finally块中,其中 try 块包含 lock 后的代码,以避免在出现异常或早期返回< code >E 237时锁从未被解锁的情况。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72853247

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档