1 package chat.business; 2 3 import java.util.Vector ; 4 import java.util.Enumeration ; 5 6 7 94 public class Discussion implements Runnable { 95 96 static private Vector contents = new Vector (); 98 99 static private long totalReceived = 0; 101 102 static private long lastStateChangeTime = System.currentTimeMillis(); 104 105 static private int numWaiting = 0; 107 108 static private Discussion singleton; 110 111 static private Thread harvester; 114 115 static private int lifetimeSec = 300; 117 static private int intervalSec = 10; 118 119 public static int maxQueueSize = 200; 121 122 123 127 private Discussion() { 128 } 129 130 131 135 public static void addMessage(String name, String text) { 136 MessageImpl msg = new MessageImpl(name, text); 137 synchronized (contents) { 138 totalReceived++; 140 contents.addElement(msg); 141 while ((maxQueueSize > 0) && (contents.size() > maxQueueSize)) 143 contents.removeElementAt(0); 144 updateCurrentState(); 147 } 148 } 149 150 151 152 159 static private void updateCurrentState() { 160 long now = System.currentTimeMillis(); 161 synchronized (contents) { 162 if (now <= lastStateChangeTime) 165 lastStateChangeTime++; 167 else 168 lastStateChangeTime = now; 170 contents.notifyAll(); 172 } 173 } 174 175 176 177 181 static public void clear() { 182 synchronized (contents) { 183 contents.removeAllElements(); 184 updateCurrentState(); 185 } 186 } 187 188 189 192 static public long getTotalReceived() { 193 return totalReceived; 194 } 195 196 197 200 static public long getCurrentSize() { 201 return contents.size(); 202 } 203 204 205 226 public static SnapshotImpl getContents(long currentState, long wait) { 227 waitForNewMessage(currentState, wait); 228 return new SnapshotImpl((Vector ) contents.clone(), lastStateChangeTime); 229 } 230 231 232 233 240 private static void waitForNewMessage(long browserState, long wait) { 241 if ((browserState != lastStateChangeTime) || (wait <= 0)) 242 return; 244 long now = System.currentTimeMillis(); 245 long giveUpTime = now + (wait * 1000); 246 while (browserState == lastStateChangeTime) { 248 long leftToGo = giveUpTime - now; 249 if (leftToGo <= 0) 250 break; 252 synchronized (contents) { 253 numWaiting ++; 257 try { 258 contents.wait(leftToGo); 259 } catch (InterruptedException e) { 260 } finally { 261 numWaiting--; 262 } 263 } 264 now = System.currentTimeMillis(); 265 } 266 } 267 268 269 273 public static int getNumWaiting() { 274 return numWaiting; 275 } 276 277 278 279 283 public void run() { 284 while (true) { 285 288 long now = System.currentTimeMillis(); 289 long wakeUp = now + (intervalSec * 1000); 290 while (now < wakeUp) { 291 long leftToGo = wakeUp - now; 292 if (leftToGo <= 0) 293 break; 294 try { 295 Thread.sleep(leftToGo); 296 } catch (InterruptedException e) { 297 } 298 now = System.currentTimeMillis(); 299 } 300 305 boolean dirty = false; 306 synchronized (contents) { 307 long expires = System.currentTimeMillis() - 308 (1000 * lifetimeSec); 309 Enumeration e = contents.elements(); 310 while (e.hasMoreElements()) { 311 MessageImpl msg = (MessageImpl) e.nextElement(); 312 if (msg == null) 313 continue; 314 if (msg.getWhen() < expires) { 315 contents.removeElement(msg); 317 dirty = true; 318 } 319 } 320 } 321 326 if (dirty) { 327 synchronized (contents) { 328 updateCurrentState(); 329 } 330 } 331 } 333 } 334 335 336 358 static public void startHarvester(int lifetimeSec, int intervalSec) { 359 if ((harvester == null) || !harvester.isAlive()) { 361 Discussion.lifetimeSec = lifetimeSec; 362 Discussion.intervalSec = intervalSec; 363 if (singleton == null) 364 singleton = new Discussion(); 365 harvester = new Thread (singleton); 366 harvester.start(); 367 } 368 } 369 static public void stopHarvester(){ 370 if ((harvester != null) || harvester.isAlive()) { 371 harvester.stop(); 372 } 373 374 } 375 376 } 377 378 379 | Popular Tags |