【问题标题】:Limit concurrent method executions inside call()限制 call() 内的并发方法执行
【发布时间】:2016-02-25 08:37:44
【问题描述】:

我的代码中有一个 call() 方法,它根据某些条件调用特定的方法:

call(){
  if(a){
      methodA(); 
  }
  if(b){
      methodB(); 
  }
  if(c){
      methodC(); 
  }
}

在上面的场景中,我想限制methodC的并发执行。 如何实现?

【问题讨论】:

  • 您能否更具体地说明“限制”的含义?
  • 假设多个线程(例如 10 个线程)正在调用 call() 方法,并且对于所有线程 if(c) 返回 true,那么一次只有特定数量的线程(例如 3 个)应该执行方法C同时进行。其他线程将在这 3 个线程完成任务后执行。因此,将methodC的并发执行限制为3

标签: multithreading callable


【解决方案1】:

您需要的是 Semaphore 构造(检查示例中的保镖/夜总会规范)。

// Create the semaphore with 3 slots, where 3 are available.
var bouncer = new Semaphore(3, 3);

call(){
  if(a){
      methodA(); 
  }
  if(b){
      methodB(); 
  }
  if(c){
      // Let a thread execute only after acquiring access (a semaphore to be released).
      Bouncer.WaitOne(); 
      methodC(); 
      // This thread is done. Let someone else go for it 
      Bouncer.Release(1); 
  }
}

【讨论】:

    【解决方案2】:

    如果您想将并发执行的数量限制为一次最多一个,那么您应该使用Lock。在 Java 中应该是这样的:

    final Lock lock = new ReentrantLock();
    call() {
      if(a) {
          methodA(); 
      }
      if(b) {
          methodB(); 
      }
      if(c) {
          lock.lock();
          try {
             methodC(); 
          } finally {
             lock.unlock();
          }
      }
    }
    

    如果你想限制一次并发执行的数量超过一个,你可以使用Semaphore;这里 CONCURRENT_CALLS_ALLOWED 是一个 int。

    final Semaphore semaphore = new Semaphore(CONCURRENT_CALLS_ALLOWED);
    call() {
      if(a) {
          methodA(); 
      }
      if(b) {
          methodB(); 
      }
      if(c) {
          semaphore.aquire();//throws checked exception
          try {
             methodC(); 
          } finally {
             semaphore.release();
          }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-07-26
      • 1970-01-01
      • 1970-01-01
      • 2011-07-25
      • 2014-04-02
      • 1970-01-01
      • 2017-04-15
      • 2014-07-19
      • 1970-01-01
      相关资源
      最近更新 更多