runMonitor(SLEEP, null, null, null, null);
try { Thread.sleep(sleepTime); } catch (InterruptedException e) { System.err.println(e); }
    private void updateTimeValues() {	int i=0;	J3dThreadData lastThread=null;	J3dThreadData thread=null;	long lastTime = currentTime;	currentTime = getTime();	J3dThreadData threads[] = (J3dThreadData []) 	                        stateWorkThreads.toArray(false);	int size = stateWorkThreads.arraySize();	while (i<lastTransformStructureThread) {	    thread = threads[i++];	    if ((thread.lastUpdateTime > thread.lastRunTime) && 		!thread.thread.userStop) {		lastThread = thread;		thread.needsRun = true;		thread.threadOpts = J3dThreadData.CONT_THREAD;		thread.lastRunTime =  currentTime;	    } else {		thread.needsRun = false;	    }	}		if (lastThread != null) {	    lastThread.threadOpts =  J3dThreadData.WAIT_ALL_THREADS;	    lastThread = null;	}		while (i<lastStructureUpdateThread) {	    thread = threads[i++];	    if ((thread.lastUpdateTime > thread.lastRunTime) &&		!thread.thread.userStop) {		lastThread = thread;		thread.needsRun = true;		thread.threadOpts = J3dThreadData.CONT_THREAD;		thread.lastRunTime = currentTime;	    } else {		thread.needsRun = false;	    }	}	if (lastThread != null) {	    lastThread.threadOpts = J3dThreadData.WAIT_ALL_THREADS;	    lastThread = null;	}		while (i<size) {	    thread = threads[i++];	    if ((thread.lastUpdateTime > thread.lastRunTime) && 		!thread.thread.userStop) {		lastThread = thread;		thread.needsRun = true;		thread.threadOpts = J3dThreadData.CONT_THREAD;		thread.lastRunTime = currentTime;	    } else {		thread.needsRun = false;	    }	}	if (lastThread != null) {	    lastThread.threadOpts = J3dThreadData.WAIT_ALL_THREADS;	    lastThread = null;	}		threads = (J3dThreadData []) renderWorkThreads.toArray(false);	size = renderWorkThreads.arraySize();	View v = null;	J3dThreadData lastRunThread = null;	waitTimestamp++;	sleepTime = Long.MAX_VALUE;	boolean threadToRun = false;	boolean needToSetWork = false;	for (i=0; i<size; i++) {	    thread = threads[i];	    if (thread.canvas == null) { // Only for swap thread		((Object []) thread.threadArgs)[3] = null;	    }	    if (thread.view != v) {		thread.view.computeCycleTime();		if (thread.view.sleepTime < sleepTime) {		    sleepTime = thread.view.sleepTime;		}	    }	    if ((thread.lastUpdateTime > thread.lastRunTime) &&		!thread.thread.userStop) {				if (!thread.view.isMinCycleTimeAchieve) {		    thread.needsRun = false;		    needToSetWork = true;		    continue;		}		if (thread.thread.lastWaitTimestamp == waitTimestamp) {		    // This renderer thread is repeated. We must wait 		    // until all previous renderer threads done before		    // allowing this thread to continue. Note that		    // lastRunThread can't be null in this case.		    waitTimestamp++;		    if (thread.view != v) {			// A new View is start			v = thread.view;			threadToRun = true;			lastRunThread.threadOpts =			    (J3dThreadData.STOP_TIMER |			     J3dThreadData.WAIT_ALL_THREADS);			((Object []) lastRunThread.threadArgs)[3] = lastRunThread.view;			thread.threadOpts = (J3dThreadData.START_TIMER |					     J3dThreadData.CONT_THREAD);		    } else {			if ((lastRunThread.threadOpts &			     J3dThreadData.START_TIMER) != 0) {			    lastRunThread.threadOpts = 				(J3dThreadData.START_TIMER |				 J3dThreadData.WAIT_ALL_THREADS);			    			} else {			    lastRunThread.threadOpts =				J3dThreadData.WAIT_ALL_THREADS;			}			thread.threadOpts = J3dThreadData.CONT_THREAD;					    }		} else {		    if (thread.view != v) {			v = thread.view;			threadToRun = true;			// Although the renderer thread is not			// repeated. We still need to wait all			// previous renderer threads if new View			// start.			if (lastRunThread != null) {			    lastRunThread.threadOpts =				(J3dThreadData.STOP_TIMER |				 J3dThreadData.WAIT_ALL_THREADS);			    ((Object []) lastRunThread.threadArgs)[3]				= lastRunThread.view;			}			thread.threadOpts = (J3dThreadData.START_TIMER |					     J3dThreadData.CONT_THREAD);		    } else {			thread.threadOpts = J3dThreadData.CONT_THREAD;		    }		}		thread.thread.lastWaitTimestamp = waitTimestamp;		thread.needsRun = true;		thread.lastRunTime = currentTime;		lastRunThread = thread;	    } else {		thread.needsRun = false;	    }	}	if (lastRunThread != null) {	    lastRunThread.threadOpts = 				(J3dThreadData.STOP_TIMER |				 J3dThreadData.WAIT_ALL_THREADS|				 J3dThreadData.LAST_STOP_TIMER);	    lockGeometry = true; 	    ((Object []) lastRunThread.threadArgs)[3] = lastRunThread.view;	}  else {	    lockGeometry = false;	}	    	if (needToSetWork && !threadToRun) {	    sleepTime -= (currentTime - lastTime);	    if (sleepTime > 0) {		runMonitor(SLEEP, null, null, null, null);	    }	    // Need to invoke MC to do work 	    // next time after sleep	    setWork();	}    }