java中http会话刷新的多线程同步

aelbi1ox  于 2021-07-06  发布在  Java
关注(0)|答案(0)|浏览(201)

我正在尝试使我的http会话刷新功能同步。我正在使用rxjava和改型。为了简单起见,这是我的函数,其中包含一些代码:

public void refreshSession(){
  fetchNewSession(...).flatMap(response -> {
    if(response.isSuccessful()) {
       storeNewSessionId(response.headers().get("sessionId"));
       return Observable.empty();
    } else {
       throw new MyHTTPException(response);
    }
  }).doOnError(throwable -> {
     Thread.currentThread().interupt();
  }).blockingSubscribe();
}

所以我要做的是同步这个函数,这样只有一个线程获取新会话,而其他线程等待。这是我试图实现的一些伪代码:

public void refreshSession(){
  if(!sessionNotRefreshed){
    fetchNewSession();
  } else {
    wait();
  }
}

因此,当新的http请求与过期的会话一起发送时,我得到的响应是会话无效,并阻塞线程,直到会话被刷新,之后http请求将与刷新的会话一起重新发送。我尝试了以下方法(这可能是非常错误的,joshua bloch在他的书effective java programming中说,我们应该使用一些更高级的api来通知和等待):

private final Object LOCK = new Object();
private volotile booleand sessionRefreshed = true;
public void refreshSession(){
   try {
     if(!sessionRefreshed){
        synchronized(LOCK){
           LOCK.wait();
        }
     } else {
       sessionRenewed = false;
       fetchNewSession(...).flatMap(response -> {
         if(response.isSuccessful()) {
           storeNewSessionId(response.headers().get("sessionId"));
           return Observable.empty();
         } else {
           throw new MyHTTPException(response);
         }
       }).doOnError(throwable -> {
         Thread.currentThread().interupt();
       }).blockingSubscribe();
    }
  } finally {
    synchronized (LOCK) {
      LOCK.notifyAll();
    }
    sessionRenewed = true;
  }
}

还有这个:

private final CountDownLatch LOCK = new CountDownLatch(1);
private volotile booleand sessionRefreshed = false;
public void refreshSession(){
   if(!sessionRefreshed){
     sessionRenewed = true;
     fetchNewSession(...).flatMap(response -> {
       if(response.isSuccessful()) {
         storeNewSessionId(response.headers().get("sessionId"));
         return Observable.empty();
       } else {
         throw new MyHTTPException(response);
       }
     }).doOnError(throwable -> {
       Thread.currentThread().interupt();
     }).blockingSubscribe();
      LOCK.countDown();
      sessionRefreshed = false;
   } else {
     LOCK.await();
   }
}

但这只适用于线程的第一次调用,因为计数达到0。我可以在 LOCK = new CountDownLatch(1); 但我认为倒计时锁不适合这样的事情。有condition和reentrantlock api以及phaser api,但我不知道如何使用它们。我也尝试不同步:

private final CountDownLatch LOCK = new CountDownLatch(1);
private volotile booleand sessionRefreshed = false;
public void refreshSession(){
   if(!sessionRefreshed){
     sessionRenewed = true;
     fetchNewSession(...).flatMap(response -> {
       if(response.isSuccessful()) {
         storeNewSessionId(response.headers().get("sessionId"));
         return Observable.empty();
       } else {
         throw new MyHTTPException(response);
       }
     }).doOnError(throwable -> {
       Thread.currentThread().interupt();
     }).blockingSubscribe();
      Schedulers.io().createWorker().schedule(() -> {
         sessionRefreshed = false;
      }, 5, TimeUnit.SECONDS);
   } else {
   }
}

不允许多个线程在5秒内同时获取会话。这些都正确吗?有更好的解决方案吗?

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题