2016-05-12 3 views
0

Java v1.7とSpring Boot v1.3.3.RELEASEを使用しています。私は認証が必要な残りのエンドポイントを打つクラスを作成しようとしています。私が要求間に資格情報を保存するたびに私がログインしないように。使用しているセッションの有効期限が切れている場合は、再度ログインして再試行します。ログインしてスレッドセーフな方法でリクエストする

擬似コード:

try 
{ 
    getData(credentials); 
} 
catch (UnauthorizedException e) 
{ 
    credentials = login(); // Multiple threads could get to this point 
    getData(credentials); 
} 

ただし、このコードは、マルチスレッド化することであると私はあまりにも多くのセッションを作成防ぐことができますどのように動作するように苦労しています。

アイデア歓迎。

答えて

1

その例外は別の理由たびに再スローされますが、これは動作するはずならばあなたは永遠にループしないようにする必要があります:

for (;;) { 
    Credentials local = credentials; 
    try { 
     getData(local); 
     break; 
    } 
    catch (UnauthorizedException e) { 
     synchronized (this) { 
      if (credentials == local) { 
       credentials = login(); 
      } 
     } 
    } 
} 

1つのスレッドだけがloginメソッドを呼び出すことができるはずです。他のスレッドは同期ブロックで待機し、別のスレッドによって更新されたことを認識してgetData()を再試行します。

+0

これを微調整する必要がありますが、これは非常に良いスタートです。アイデアをありがとう。 – bm1729

0

ログインメソッドへのアクセスを同期する必要があると思うので、1つのスレッドだけがそれにアクセスして資格情報を設定できます。別のスレッドを入力したい場合は、それを待たなければならず、資格はすでにロックを保持しているスレッドによって設定されます。

擬似コード:それの外

try { 
    getData(credentials); 
} catch (UnauthorizedException e) { 
    synchronize(lockObject) { 
     if (credentials == null) { 
      credentials = login(); 
      getData(credentials); 
     } 
    } 
} 

次の場合が動作することを保証するために、nullに資格情報を設定する必要があります。

+0

これはいくつかの理由で機能しません。最初に、資格証明は期限切れになるとヌルではなく、複数のスレッドがキャッチに入ったらそれぞれ試してログインします.3番目に、誰もがgetDataで2度目のチャンスを得るはずです。私はReEntrantLockで何か考えていますか? – bm1729

+0

私の答えで私はちょうど擬似コードソリューションを提供します。主な答えは、アクセスを同期することです。 synchronizedキーワードでReAntrantLockを実行しても問題はありません。 –

関連する問題