信号量tryAcquire()方法不会立即返回

时间:2019-10-12 22:21:41

标签: java

信号量中的方法tryAcquire(long timeout, TimeUnit unit)不会立即返回。线程不会被阻塞,并且即使其中一个线程正在获取信号量,也允许所有线程都获取信号量。 当代理正在通知订户关于同一主题的先前发布消息的状态信息更改时,我正在尝试对发布消息实施流控制。

我使第一个线程获取了信号量,然后释放了信号量,然后睡眠了10秒钟;与此同时,我使另一个线程获取了信号量,而第一个线程仍然处于睡眠状态10秒钟,而第二个线程仍然可以获取信号量。如果信号灯不可用,我希望程序立即返回。 不知道是什么问题。任何建议都会很有帮助。

try {

if(semaphore.tryAcquire(this.request_handling_time, 
TimeUnit.MILLISECONDS)) {
updateResource(resource, request);
response = channel.createResponse(request, CoapResponseCode.Changed_204);   
                                        logger.info("content changed");                                 
try {

if(request.getMaxAgeTopic()>=0) {

((PubSubTopic) resource).setmaxAgeTopicValue(request.getMaxAgeTopic());
}
}catch(NullPointerException ex){

    if(((PubSubTopic) resource).getmaxAgeTopicValue() > 0){
        ((PubSubTopic) resource).updateTopicLifeTime();
    }
}                                   
resource.changed(); // send notifications to the subscribers

// send notifications to the pendingRequest Clients if present
if(((PubSubTopic) resource).getPendingSubscribe().size() > 0) {
    ((PubSubTopic) resource).notifyPendingRequest();
}           
try {
        Thread.sleep(10000);        


    }
    catch (@SuppressWarnings("unused") InterruptedException e){
     /*do nothing*/
  }

semaphore.release();
}else {
    logger.info("Too many requests on topic "+resource.getPath());                                  
 response = channel.createResponse(request, 
 CoapResponseCode.Too_Many_Requests_429);   

 response.setMaxAge(retry_time_after_too_many_requests);
                                    }
} catch (InterruptedException e) {
   // TODO Auto-generated catch block
e.printStackTrace();
}finally {
semaphore.release();
}

1 个答案:

答案 0 :(得分:3)

  信号量中的

tryAcquire(long timeout, TimeUnit unit)方法不会立即返回。

不应该这样。如果您阅读文档,即javadoc,则会发现:

  

如果没有可用的许可,则出于线程调度目的,当前线程将被禁用,并且处于休眠状态,直到发生以下三种情况之一:

     
      
  • 其他一些线程为此信号量调用release()方法,接下来将为当前线程分配许可;或
  •   
  • 其他一些线程中断当前线程;或
  •   
  • 已过指定的等待时间
  •   

如果您希望它立即返回,请致电tryAcquire()(不带参数):

  

如果没有许可,则此方法将立即返回,值为false