10

I need to add delay without using Thread.sleep() or a while loop doing nothing. The game im editing(Minecraft) clock runs on "Ticks" but they can fluctuate depending on your FPS.

public void onTick() {//Called every "Tick"
    if(variable){ //If my variable is true
            boolean = true; //Setting my boolean to true
            /**
            *Doing a bunch of things.
            **/
            //I need a delay for about one second here.
            boolean = false; //Setting my boolean to false;
    }
}

The reason why i need a delay is because if i dont have one the code runs too fast and misses it and does not toggle.

Keppil
  • 45,603
  • 8
  • 97
  • 119
user3166950
  • 315
  • 3
  • 6
  • 15
  • 1
    Why can't you use `Thread.sleep()`? – Keppil Jan 06 '14 at 21:42
  • Adding an arbitrary delay because code "runs too fast" is a *major* code smell. Holding up an entire thread for a second at a time is also completely unacceptable in most situations. More details would be useful in helping you find a better solution here. – Chris Hayes Jan 06 '14 at 21:45
  • I cant use Thread.sleep() because it freezes the whole game for the amount of time you set. – user3166950 Jan 06 '14 at 21:46
  • 1
    So,how do you think putting some arbitrary loop us going to help? Thread.sleep doesn't consume CPU cycles like a loop will...it sounds like you have a design problem. You need to yes a separate thread to handle updates to the game model, schedule repaints and control the frame rate, using something like a Thread.sleep... – MadProgrammer Jan 06 '14 at 21:47
  • You can use http://docs.oracle.com/javase/7/docs/api/java/util/Timer.html to schedule the change to false to future time, but on every next tick the if would be executed. Maybe getting ticks to often is the problem? – Krystian Lieber Jan 06 '14 at 21:51
  • 1
    I'm almost positive you're in over your head, and this isn't going to work the way you think it will. You need to do some research on threads. The real question is, why do you think you need a delay? Because I promise this is the wrong solution. – SpacePrez Jan 06 '14 at 21:52
  • I know you got an answer that you like, but I'm just as convinced as @Zaphod42 that it's the wrong approach. What kinds of "a bunch of things" are you doing? Do they check the value of your boolean? Why can't you just wait until the "bunch of things" is done? (Vague suspicion: are some of those "bunch of things" done in a different thread?) – Erick G. Hagstrom Aug 30 '15 at 19:15

3 Answers3

11

Something like the following should give you the delay you need without holding up the game thread:

private final long PERIOD = 1000L; // Adjust to suit timing
private long lastTime = System.currentTimeMillis() - PERIOD;

public void onTick() {//Called every "Tick"
    long thisTime = System.currentTimeMillis();

    if ((thisTime - lastTime) >= PERIOD) {
        lastTime = thisTime;

        if(variable) { //If my variable is true
            boolean = true; //Setting my boolean to true
            /**
            *Doing a bunch of things.
            **/
            //I need a delay for about one second here.
            boolean = false; //Setting my boolean to false;
        }
    }
}
clstrfsck
  • 14,715
  • 4
  • 44
  • 59
6
long start = new Date().getTime();
while(new Date().getTime() - start < 1000L){}

is the simplest solution I can think about.

Still, the heap might get polluted with a lot of unreferenced Date objects, which, depending on how often you get to create such a pseudo-delay, might increase the GC overhead.

At the end of the day, you have to know that this is no better solution in terms of processor usage, compared to the Thread.sleep() solution.

Andrei Nicusan
  • 4,555
  • 1
  • 23
  • 36
1

One of approaches is :

class Timer {
            private static final ScheduledExecutorService scheduledThreadPoolExecutor = Executors.newScheduledThreadPool(10);
    
            private static void doPause(int ms) {
                try {
                    scheduledThreadPoolExecutor.schedule(() -> {
                    }, ms, TimeUnit.MILLISECONDS).get();
                } catch (Exception e) {
                    throw new RuntimeException();
                }
            }
        }

and then you can use Timer.doPause(50) where you need.

ActivX
  • 176
  • 4