1.Class类的running
用于主线程的Client
和若干 ClientConnection 线程之间 共享Client的running变量
public class
Client {
public
AtomicBoolean running = newAtomicBoolean(true); // if client runs
public void
stop() {
...............
if(!
running.
compareAndSet(true, false)) {
return;
}
.................
}
private ClientConnection
getConnection(ClientConnectionId remoteId,
ClientCallcall)
throwsIOException, InterruptedException {
if(!
running.
get()) {
//the client is stopped
thrownew IOException("The client is stopped");
}
}
public class
ClientConnection extends
Thread {
private synchronizedboolean
waitForWork() {
if(calls.isEmpty() && !shouldCloseConnection.get()
&&
client.running.get())
{
long timeout = maxIdleTime-
(System.currentTimeMillis()-lastActivity.get());
if (timeout>0) {
try {
wait(timeout);
} catch (InterruptedExceptione) {}
}
}
if (!calls.isEmpty()&& !shouldCloseConnection.get() &&
client.running.
get()) {
return true;
}
。。。。。。。。。。。。。。
}
public class
ClientConnectionPingInputStream extendsFilterInputStream {
private void
handleTimeout(SocketTimeoutException e) throws IOException{
if(clientConnection.shouldCloseConnection.get() ||!
clientConnection.client.running.get()
||clientConnection.rpcTimeout > 0) {
throw e;
}else {
sendPing();
}
}
。。。。。。
}
2.
ClientConnection的
lastActivity
用于若干ClientConnection线程之间共享lastActivity
public class
ClientConnection extends
Thread {
private
AtomicLonglastActivity = new AtomicLong();// last I/O activity time
private void
touch() {
lastActivity.
set(System.currentTimeMillis());
}
private synchronizedboolean
waitForWork() {
if(calls.isEmpty() && !shouldCloseConnection.get()
&& client.running.get())
{
long timeout = maxIdleTime-
(System.currentTimeMillis()-
lastActivity.get());
if (timeout>0) {
try {
wait(timeout);
} catch (InterruptedExceptione) {}
}
}
}
}
3.
ClientConnection
的
shouldCloseConnection
用于若干ClientConnection 线程之间共享shouldCloseConnection
public class
ClientConnection extends
Thread {
AtomicBoolean
shouldCloseConnection = new AtomicBoolean();
// indicate if theconnection is closed
public synchronizedboolean
addCall(ClientCall call) {
if(
shouldCloseConnection.get())
return false;
calls.put(call.id, call);
notify();
return true;
}
public synchronized void
setupIOstreams() throws InterruptedException {
if(socket != null ||
shouldCloseConnection.get()) {
return;
}
.........
}
private synchronizedboolean
waitForWork() {
if(calls.isEmpty() && !
shouldCloseConnection.get()
&& client.running.get())
{
long timeout = maxIdleTime-
(System.currentTimeMillis()-lastActivity.get());
if (timeout>0) {
try {
wait(timeout);
} catch (InterruptedExceptione) {}
}
}
if(!calls.isEmpty() && !
shouldCloseConnection.get()&& client.running.get()) {
return true;
}else if (
shouldCloseConnection.get()) {
return false;
}else if (calls.isEmpty()) { // idle connection closed orstopped
markClosed(null);
return false;
}else { // get stopped but there are still pendingrequests
markClosed((IOException)newIOException().initCause(
newInterruptedException()));
return false;
}
}
public void
sendParam(ClientCall call) {
if(
shouldCloseConnection.get()) {
return;
}
}
private void
receiveResponse() {
if(
shouldCloseConnection.get()) {
return;
}
touch();
}
private synchronizedvoid
markClosed(IOException e) {
if(
shouldCloseConnection.compareAndSet(false, true)) {
closeException = e;
notifyAll();
}
}
private synchronizedvoid
close() {
if(!
shouldCloseConnection.get()) {
return;
}
}
}
publicclass
ClientConnectionPingInputStream extendsFilterInputStream {
privatevoid
handleTimeout(SocketTimeoutExceptione) throws IOException {
if(
clientConnection.shouldCloseConnection.get() ||!clientConnection.client.running.get()
||clientConnection.rpcTimeout > 0) {
throw e;
}else {
sendPing();
}
}
。。。。。。
}