有没有办法在java(或scala)信号量对象中包含查询方法的条件



我有一个包含许多线程的程序,让我们以六个线程为例。其中五个线程应该能够并发使用给定资源,但如果发生给定条件,最后一个线程不应该,并且应该等到该条件结束。

在我的理解中,不能使用ReentrantLock,因为它一次只能由一个线程持有。另一方面,信号量可以一次由许多线程持有,但我找不到将条件附加到获取方法的方法。

这个高级对象可以解决问题,或者我将不得不使用通知并直接等待来实现此功能?

例如。

class A{
   getResource{ ... }
}
//This Runable could be spawn many times at the same time
class B implements Runnable{
   run {
      setConditionToTrue
      getResource
      ...
      getResource
      ...
      getResource
      setConditionToFalse
   }
}
//This will be working forever but only one Thread
class C implements Runnable{
   run{
      loop{
         if(Condition == true) wait
         getResource
      }
   }
}

提前感谢朋友

我在这里重申您的问题:您希望 B 线程并发访问共享资源,但您的 C 线程应该等待某些条件发生后才能使用该资源。

如果我正确理解您的问题,您可以使用ReentrantLock来解决您的问题。

引入一个名为 getAccess() 的新函数,并使 C 线程调用此函数以获取共享资源。引入另外两个函数来允许和停止对共享资源的访问。

class A {
  private final ReentrantLock lock = new ReentrantLock();
  private Condition someCondition = lock.newCondition();
  private boolean bCondition = false;
  getResource{ ... } // Your existing method used by B threads
  getAccess() { // Protected access to some resource, called by C thread
    lock.acquire();
    try {
      if (!bCondition)
        someCondition.await(); // B thread will wait here but releases the lock
    } finally {
      lock.release();
    }
  }
  allowAccess() { // B thread can call this func to notify C and allow access
    lock.acquire();
    try {
      bCondition = true;
      someCondition.signal(); // Decided to release the resource
    } finally {
      lock.release();
    }
  }
  stopAccess() { // B thread can stop the access
    lock.acquire();
    try {
      bCondition = false;
    } finally {
      lock.release();
    }
  }
}

如果您希望多个线程共享一个资源,则需要更具体地说明该共享的含义。通常,这意味着区分读取资源当前值的线程和更改值的其他线程。这意味着如果写入是无竞争和稳定的,则是一种并发读取/独占写入模式("crew")。

在Java API中,这是由ReentrantReadWriteLock提供的。还有其他值得考虑的替代方案,例如JCSP中精心实施的船员。

使用

[J]CSP,还可以使用不同的模式:将公共资源包装在其自己的线程中,并通过共享 JCSP 通道从所有客户端线程提供对它的访问。这种客户端-服务器模式易于理解和实现,并且具有另一个好处,即它在形式上没有死锁,因为线程通信图是非循环的(更多)。

最新更新