まず、異常SelectorKeysのセットを変更
ときにモニター状態のスレッドは、待ち解除エンティティ。つまり、複数のスレッドが同じを解放するロックを待機します。
ライター・スレッドの1、
セレクタが動作状態にあるときは、この時点で呼び出すことができない、その集計を変更することはできません
key.interestOps(key.readyOps())
channel.register(selector,registerOps)
キーの変更、書き込みを読んだときに、コレクションへの変更、そのセレクタは、現在のキューをスキャンする状態ではないselect()の状態ではないので、その場合には、あなたは、セレクタ操作を呼び起こす呼び出す必要がありますに関係しています。その後、集合体の内側に行くためにキューを変更します。変更後)(セレクタが選択できるように続けることが良いこと
selector.wakeup()
2、リーダースレッドの
コールセレクタ()操作を選択し、値が0です、
readSelector.select()==0
私たちは、現在のリリースのロックを待っています
waitSelectiion(inRegInput)
ロックを解除するには、まず、現在のロッカーを取得します
そして、ロッカーがtrueの場合は、一定の正の値を示し動作している、真であるか否かを判断します。
if(locker.get())
確かに、待機操作が呼び出されたロッカー
locker.get()
完了を待った後、ロッカー想起操作を呼び出します
locker.notify()
図3は、このプロセスは非常に正しいように見えますが、致命的な欠陥があります。
例えば、各正方形はクライアントを表し、青色の正方形はL対応クライアント(読取り、書込み又は読み書き)を表し、クライアントの灰色は、準備ができていないセレクタは、継続的にエンドユーザースキャンに最初からスイープ終わり。最初から最後までスキャンする場合、クライアントの準備ができている場合は、チャネルが抽出されます。実際には、抽出されていないチャンネルは、各セットが内部selectionkeysであると言うことであるselectkeysから抽出されます。ときにこれらのキーは準備ができて、鍵はすでに準備ができて、集電selectionKeysで、その結果、別のコレクションに追加されます。キューがキュー全体をスキャンする準備ができていないとすると、それは、スキャン繰り返します。あなたは準備ができて、キーを持っている場合、それは準備の数を返します。
三度目にスキャンする場合は、このコレクションのselectionKeysを変更したいので、)、ウェイクアップ動作selector.wakeUp(の結果として、今回のスキャンを停止し、その後0に戻りますが、この結果は正しくありません。変更selectionKeys、再スキャンを目覚めたときに正しい方法では、と、スキャンを書き換えた結果を返します。
5回目のスキャン時に、操作が想起を行う、脆弱性は、2は、この時点で戻すことができます。キーをスキャンするとき、なぜすぐには戻りませんか?キューに少なくとも必要が再びそれをスキャンしますので、結果を返します。それがウェイクアップコールを強制するため結果として、途中でバックアップ。
アプローチが正しいか、復帰は2で、組立は、現在のスキャン操作の完了を待つ必要があります。スキャンが完了すると、2つの前に消費され、その後、スキャンヘッド重量に結果を返します。
変化の様子であります
AtomicBoolean locker = inRegInput;
else if(locker.get()){
waitSelection(inRegInput);
}
状態の変化した場合、待ち続けます。しかし、あなたは続行する必要はありません。ゼロから継続して、再度開始するので。しかし、彼は現在の操作の完了を待って、言った、その後、現在のトランザクション処理を継続します。
データが除去されると、これに代えて、データのバグの除去をもたらすによる変化へのループに使用イテレータ
読み取り操作のために、また適用されます。
第二に、状態変更とSelectionKey
コレクション、アウト除去する際にその関心のコレクションに興味セレクタ金利を変更します。実際には、除去のためにキューです。同期動作のために必要があるので。
このメソッドは、状態がを選択してはならない、起動され、偽の値に、その真のロッカーを変更する必要はありません。
ときにあなたが原因閉鎖メソッド呼び出しkey.cancel()リードにセットを変更するときに例外が発生する可能性があり、変更とSelectionKey状態。
第三に、この方法をキャンセル
このスレッドは、()操作を選択すると、あなたが()channel.registerを呼び出す場合、key.clear key.interestOpsは()、()上記の変更の組み合わせを含むことになります。
変更は除去または新しい操作以外の何ものでもありません、この時間は、セレクタが起きて終了です許可する必要があります。この時点で、より多くのロック状態を必要とし、終了して現在の状態を知っている、あなたは待つ必要があります。