Concurrent client BUG repair and optimize the performance of a

 

First, change the set of abnormal SelectorKeys

When a thread in Monitor state, the wait release entity. Ie multiple threads wait for a lock to release the same.

1, for the writer thread

When Selector is in working condition, is not allowed to change its aggregate, that can not be called at this time

key.interestOps(key.readyOps())
channel.register(selector,registerOps)

When reading the key change, write, are related to changes to the collection, in which case, you must call the Selector evokes operation, so that selector is not in the select () state, that is not in a state to scan the current queue. Then change the queue to go inside the aggregates. After the change be good to continue to let the selector select ()

selector.wakeup()

2, for the reader thread

The call selector select () operation, when the value is 0,

readSelector.select()==0

We will wait for the current release locks

waitSelectiion(inRegInput)

In releasing the lock, the first to get the current locker

Then determines whether the locker is true, if true, is operating demonstrate certain positive value.

if(locker.get())

True, the wait operation is invoked locker

locker.get()

After waiting for completion, call the locker evoke operation

locker.notify()

3, this process appears to be very correct, but there is a fatal flaw.

For example, each square represents a client, a blue square represents L-ready client (read, write or read-write), gray for the client is not ready, then Selector continually swept from the beginning to the end customer scans end. When scanning from the beginning to the end, if the client is ready, the channel will be extracted. In fact, the channel is not extracted, is extracted from the selectkeys, that is to say that each set is selectionkeys inside. When these key ready, the key will be added to another collection, resulting in the current collection selectionKeys already ready. When the queue is not ready to scan the entire queue and it will repeat scan. If you have a ready key, it will return the number of ready.

If the scan to the third time, to stop scanning, because you want to change this collection selectionKeys, this time as a result of a wakeup operation selector.wakeUp (), then will return to 0, this result is not correct. The right way, and when awakened change selectionKeys, re-scan, return the result of rewriting scanning.

Vulnerabilities that, when scanning the fifth time, the operation performed evoke, 2 may be returned at this time. Why not return to the ready when scanning the key it? Because at least need to queue scan it again, will return the results. As the results back in the middle, because it forces the wake-up call.

Approach is correct, return is 2, the assembly should wait for completion of the current scan operation. When the scan is completed, the two front consumed, and then returns the result to the scan head weight.

Is in a state of change

AtomicBoolean locker = inRegInput;

 

else if(locker.get()){
    waitSelection(inRegInput);
}

If the change in status, continue to wait. But you do not need to continue. Because continue from scratch and start again. But he said, after waiting for the completion of the current operation, and then continue the current transaction processing.

 

When the data is removed, use a for loop due to changes result in removal of data bug, so instead iterator

For read operations, also apply.

Second, the state change selectionKey

Changing interest selector interest in the collection, a collection of its interest in removing out. In fact, it is a queue for removal. So the need for synchronous operation.

This method is invoked, the state must not select is, there is no need to change its true the locker, to false values.

When change selectionkey state when an exception may occur when you change the set due to the closure method calls key.cancel () lead.

Third, cancel method

When this thread select () operation, if you call channel.register (), key.interestOps (), key.clear () will involve the combination of the above changes.

Change is nothing more than the removal or new operation, this time should be allowed selector is awake and exit. At this point needs more locked state, know the current state in the exit, you need to wait.

Published 174 original articles · won praise 115 · views 830 000 +

Guess you like

Origin blog.csdn.net/nicolelili1/article/details/105130942