2017-01-19 9 views
2

私の場合、特定のメソッドは、同期と非同期のモードベースで条件に基づいて実行されます。いくつかの条件で同期モードと非同期モードを切り替える

私がしているのは、スイッチを行うためにreentrantlockを使用することです。コードは以下のようになります。

private Lock modeLock = new ReentrantLock(true); 
public void specialMethod(boolean condition)} 
    Callable<Result> c =() -> { 
     if(condition) 
      modeLock.lock(); 
     else{ 
      try { 
       modeLock.tryLock(1, TimeUnit.DAYS); 
      } catch (InterruptedException e) { 
      } finally { 
       modeLock.unlock(); 
      } 
     //do something here 
     if(condition) 
      modeLock.unlock(); 
     return result; 
    }; 
    pool.submit(c); 
} 

それは私のために働くが、非常にばかばかしいようだ。私はReentrantLockからConditionによって改善できると思うが、何の手がかりもない。どのようにそれを改善する方法を教えてもらえますか? Thx

+0

だから、時にはそれがスレッドセーフだと言って、時にはしていませんか?それは奇妙に聞こえる。 – Kayaman

+0

@Kayamanはい。それは強いですが、私たちの実際のケースで発生します。特別なアクションによっては、すべての場合のプロセス結果に影響を与える場合があります。このような要求を処理する必要があります。 – Roy

+0

これが私のコードベースであれば、私は実際の問題を解決しようとします。これは単に症状を修正しているようです。 「ハーフスレッドセーフ」というコードは、より深い設計上の問題のようです。 – Kayaman

答えて

0

Java CollectionssynchronizedCollection(Collection<T> c)メソッドを、おそらく実行しようとしているパターンとして使用できます。

クラスのインターフェイスを定義し、ロック/アンロックロジックを実行するラッパーを配置してビジネスロジックを元の非同期クラスに委任して同期を達成します。ラッパーはインターフェイスを実装します(つまり、specialMethodを実装します)が、実際のロジックを行うために元のクラスを呼び出してロックしてロックを解除してから呼び出します。

フラグをメソッドに渡す代わりに、クラスのオブジェクトを作成して、どのクラスのクラスを作成するかを指定します。元のクラスまたは元のクラスと同期ラッパーです。

(やや簡単なアプローチ)、クラスの拡張子(例:SynchronizedClassName extends ClassName)を作成し、specialMethodを上書きします。そこで(無条件に)ロックして、スーパークラスのロジックを呼び出します。

また、同期または非同期を切り替えるオブジェクトを決定します。

シンクロナイズされたラッパーが含まれている非クリニカルクラスを公開している場合は、同期アクセスと非同期アクセスを切り替える場合にアクセスできます。

例:

interface SpecialInterface { 
    void specialMethod(); 
} 

// Original class 
class SpecialClass implements SpecialInterface { 
    public void specialMethod() { 
     ... // logic with no locking 
} 

class SynchronizedSpecialClass implements SpecialInterface { 
    private SpecialClass logic; 
    private Lock modeLock = new ReentrantLock(true); 

    public SynchronizedSpecialClass(SpecialClass logic) { 
     this.logic = logic; 
    } 

    public void specialMethod() { 
     try { 
      modeLock.lock(); 
      logic.specialMethod(); 
     } finally { 
      modelock.unlock(); 
     } 
    } 
} 

// use 
SpecialInterface o = new SpecialClass(); 
if (lockingRequired) o = new SynchronizedSpecialClass(o); 
関連する問題