1 14 15 package org.quickserver.util.pool.thread; 16 17 import java.util.logging.*; 18 import java.util.*; 19 import org.quickserver.util.MyString; 20 import org.quickserver.net.server.ClientHandler; 21 import org.quickserver.net.server.ClientEvent; 22 23 29 public class ClientThread extends Thread { 30 private static Logger logger = Logger.getLogger(ClientThread.class.getName()); 31 private static Map idMap = new HashMap(); 32 33 private String name = "<ClientThread-Pool#"; 34 private ClientPool pool; 35 private Runnable client; 36 private int id; 37 private boolean ready = false; 38 39 52 protected volatile char state = 'U'; 53 54 public boolean isReady() { 55 return ready; 56 } 57 58 public void clean() { 59 client = null; 60 } 61 62 public ClientThread(ClientPool pool) { 63 this(pool, -1); 64 } 65 66 static class InstanceId { 67 private int id = 0; 68 public int getNextId() { 69 return ++id; 70 } 71 }; 72 73 private static int getNewId(int instanceCount) { 74 InstanceId instanceId = (InstanceId) idMap.get(""+instanceCount); 75 if(instanceId==null) { 76 instanceId = new InstanceId(); 77 idMap.put(""+instanceCount, instanceId); 78 } 79 return instanceId.getNextId(); 80 } 81 82 public ClientThread(ClientPool pool, int instanceCount) { 83 id = getNewId(instanceCount); 84 name = name+instanceCount+"-ID:"+id+">"; 85 this.pool = pool; 86 setName(name); 87 } 88 89 public int getInstanceId() { 90 return id; 91 } 92 93 private void executeClient() { 94 boolean niowriteFlag = false; 95 state = 'R'; 96 97 if(ClientHandler.class.isInstance(client)) { 98 niowriteFlag = ((ClientHandler) client).isClientEventNext(ClientEvent.WRITE); 99 if(niowriteFlag) { 100 pool.nioWriteStart(); 101 } 102 } else { 103 niowriteFlag = false; 104 } 105 106 try { 107 client.run(); 108 } catch(RuntimeException e) { 109 logger.warning("RuntimeException @ thread run() : "+getName()+": "+MyString.getStackTrace(e)); 110 } finally { 111 if(niowriteFlag) { 112 pool.nioWriteEnd(); 113 } 114 } 115 state = 'I'; 116 } 117 118 public void run() { 119 state = 'S'; 120 121 if(pool.isClientAvailable()==true) { 122 ready = true; 123 synchronized(pool) { 124 pool.notify(); 125 } 126 } 127 128 boolean returnToPool = false; 129 while(true) { 130 if(ready) { 131 state = 'L'; 132 client = pool.getClient(); 133 if(client==null) { 134 logger.fine("ClientPool returned a null client! Other Thread must have taken my client.. Ok"); 135 } else { 136 executeClient(); 137 logger.finest("Client returned the thread: "+getName()); 138 client = null; 139 if(pool==null) { 140 logger.fine("Could not returning client thread "+getName()+", pool was null!"); 141 state = 'D'; 142 break; 143 } 144 } 145 146 if(pool.isClientAvailable()==true) { 147 state = 'L'; 148 continue; 149 } 150 151 returnToPool = true; 152 } 154 synchronized(this) { 155 if(ready==false) ready = true; 156 157 if(returnToPool) { 158 logger.finest("Returning client thread to pool: "+getName()); 159 pool.returnObject(ClientThread.this); 160 returnToPool = false; 161 state = 'P'; 162 } 163 164 try { 165 state = 'W'; 166 wait(); 167 state = 'N'; 168 } catch(InterruptedException e) { 169 logger.finest("Closing thread "+Thread.currentThread().getName()+" since interrupted."); 170 state = 'D'; 171 break; 172 } 173 } 174 } } 176 177 182 public Runnable getThread() { 183 return client; 184 } 185 186 190 public String toString() { 191 return super.toString()+" - "+state+" - Client "+client; 192 } 193 } 194 | Popular Tags |