信号量僵局

use*_*170 8 java multithreading deadlock semaphore

所以我使用信号量时遇到了问题.编写一个代码,其中有4个房间和一些访客.每个房间都有一定的上限,可以容纳他们可以容纳的游客数量.因此,进入一个完整的房间将触发wait().访客在进入另一个房间之前不得离开房间,因此他们总是在一个房间里.

public class Semaphore {

  private int placesLeft;

  public Semaphore(int placesInRoom) {
    this.placesLeft = placesInRoom;
  }

  public synchronized void acquire(Visitor visitor) {
    Semaphore sem = visitor.getRoom().getSemaphore();

    try {
      while (placesLeft <= 0) {
        this.wait();
    }

  } catch (InterruptedException e) {}

  sem.release();
  placesLeft--;
}

public synchronized void release() {
  placesLeft++;
  this.notifyAll();
}
Run Code Online (Sandbox Code Playgroud)

当2个人试图进入彼此的房间时出现死锁.也出于某种原因,placesLeft计数不正确.

所以我该怎么做?

编辑:

忙于其他事情,重新回答这个问题.由于房间满了,问题不会发生,当来自room1的person1想要进入room2并且同时来自room2的person2想要进入room1时,会发生锁定.因为我明白它可能与同步有关吗?它们在发布之前就会卡住,因此不会调用release.据我所知,一个房间的准确和释放不能同时调用.所以基本上room1信号量释放不能被称为cuz同时调用accuire,对于room2也是如此?我是新手编码器,同步还不是那么清楚.从一个或另一个删除同步似乎不起作用(也是错误的).

Dav*_*ess 0

添加当前访客列表,Room以便您可以检查acquire传入访客是否来自该房间的其中一位占用者正在等待进入的房间的情况。您还需要将访客等待进入的房间添加到Visitor

Room comingFrom = visitor.getRoom();
while (placesLeft <= 0) {
    for (Visitor waiter : room.getVisitors()) {
        if (waiter.getWaitingForRoom().equals(comingFrom) {
            // swap the visitors without releasing/acquiring any semaphores and return
        }
    }
    this.wait();
}
Run Code Online (Sandbox Code Playgroud)

我有点不确定检查访客是否正在等待进入当前访客要离开的同一个房间的逻辑。room给定代码我无法判断哪个房间代表哪个房间。