2012-03-02 14 views
1

書き込みロックを保持しているスレッドからタスクをForkJoinPoolまたはParallelArrayに送信したいとします。ドメインモデルへのアクセスは、現在のスレッドが関連するロックを保持していることを確認することで保護されます。 FJワーカーがタスクを実行できるようにするには(読み込み専用(クエリなど))、スレッドを生成したスレッドにアクセスチェックを委任する必要があります。ReentrantReadWriteLock親スレッドへの委任

ForkJoinWorkerThreadを、スポーンスレッドへの参照でサブクラス化しました。次に、ReentrantReadWriteLockをサブクラス化し、通常のチェックを実行するためにisWriteLockedByCurrentThreadをオーバーフローさせ、スレッドが委譲しているFJWorkerのインスタンスである場合、デリゲートスレッド(親)がロックの所有者であることをチェックします。ReentrantReadWriteLock# getOwnerメソッド()

public class DelegateAwareReentrantReadWriteLock extends ReentrantReadWriteLock { 
    @Override 
    public boolean isWriteLockedByCurrentThread() { 
     return super.isWriteLockedByCurrentThread() || isWriteLockedByDelegateThread(); 
    } 

    private boolean isWriteLockedByDelegateThread() { 
     final Thread currentThread = Thread.currentThread(); 
     if (currentThread instanceof FJAccessDelegatingWorker) { 
      final Thread delegate = ((FJAccessDelegatingWorker) currentThread).getDelegate(); 
      return delegate.equals(getOwner()); 
     } 
     return false; 
    } 
} 

しかし、documentation for getOwner()状態は次のとおりです。このメソッドは所有者ではない スレッドによって呼び出されると

、戻り値は ベストエフォートを反映しています近似現在のロック状態。たとえば、 ロックを取得しようとしているスレッドが であるにもかかわらず、ロックを取得しようとしていない場合でも、所有者が一時的にnullになることがあります。

これは、すでにアクセスが許可されているスレッド内でタスクを送信した場合、このメソッドが正しく参照を返すことを意味しています。残念ながら、これは暗示されていません。

この方法を使用できない場合、この種の委任には他にどのような選択肢がありますか?

ありがとうございます。

答えて

0

getOwner()の実装の詳細は、書き込みロックを取得したスレッドと所有者を問い合わせているスレッドとの間に発生前の関係がある場合、正しいことを保証する決定的な動作を持つと考えられます所有者が返されます。私は実装をチェックしていませんが、これはコメントが示唆しているようなものであり、ロックが獲得されている間にビヘイビアが非決定論的である可能性があることを基盤としています。

ただし、書き込みロックをダウングレードして、すべての委任チェックが(各スレッドが独自の読み取りロックを所有できるので)始めるのを避けることができれば、もっと簡単になる場合があります。おそらく、2つの別個のロック、例えば外側と内側のロックを使用することも可能であり、この場合、内側のロックは書き込みのために保持されない。

編集: getOwner()の実装では、揮発性状態変数の読み取りを行うgetState()が呼び出されます。これは、書き込みロックが保持されている場合、常にgetOwner()が親スレッドを返すようにします。 。

+0

送信スレッドは、あとで読み取りロックから書き込みロックにアップグレードできないため、最初から書き込みロックを取得します。読み取りアクセスを必要とするFJタスク(別々のFJプールスレッド内で実行)は、アクセス試行を委任できる場合を除いて、送信スレッドの書き込みロックによってブロックされます。これは達成しようとしています。 – sms1

+0

@ sms1私はgetOwner()の実装をチェックし、揮発性読み取りセマンティクス(volatile状態変数を読み込む)を保証するgetStateの読み取りを行います。これは、排他書込みロックが親スレッドによって保持されている場合、その後のgetOwnerの呼び出しが確定的に親スレッドのインスタンスを返すのに十分でなければなりません。 –

+0

間違いなく、ロックの取得後に提出が行われます。私は最初にコードを読んだことがありますが、ドキュメントの文言はこの場合のメモリセマンティクスへの私の信頼を損なっています。私はdocの例がこの状況を排除していると思うので、正しいと思います。ありがとうございました。 – sms1