2

I'm having a bit of an annoying problem. Right now, I have a snippet of code that starts a thread, sets a timer within that thread, and then exits that thread and continues with its life. My intent here was for the program to wait for the TimerTask to complete before continuing with code flow. However, obviously, setting up a new TimerTask doesn't pause execution to wait for the timer to run down.

How do I set this up so that my code reaches the TimerTask, waits for the TimerTask to expire, and then continues? Should I even be using a Timer at all? I've looked everywhere for a solution, but I Can't seem to find one.

timer = new Timer();
    Thread t = new Thread(new Runnable(){
        boolean isRunning = true;
        public void run() {
            int delay = 1000;
            int period = 1000;
            interval = 10;
            timerPanel.setText(interval.toString());

            //Scheduling the below TimerTask doesn't wait
            //for the TimerTask to finish before continuing
            timer.scheduleAtFixedRate(new TimerTask() { 

                public void run() {
                    timerPanel.setText(setInterval().toString());
                }
            }, delay, period);

            System.out.println("Thread done.");
        }
    });
    t.start();

    try {
        t.join(); //doesn't work as I wanted
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    endTask();

Thanks in advance.

EDIT: Sorry for the confusion about the repeated task. I need the task to repeat because it's a countdown timer that pulses every second from 10 to 0. The function setInterval() eventually cancels the timer. Here's the relevant code:

private final Integer setInterval() {
    if (interval == 1)
        timer.cancel();
    return --interval;
}
rkoth
  • 133
  • 1
  • 3
  • 10
  • Have you tried [Thread.sleep](http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#sleep(long))? – default locale Jul 01 '13 at 13:43
  • You have scheduled a repeated task, it's never going to complete. – Marko Topolnik Jul 01 '13 at 13:46
  • 4
    If you have it scheduled - it will repeat. If you don't need to repeat it and need to waitr until it finishes - you don't need it. just create a method and call it – Tala Jul 01 '13 at 13:47
  • The task needs to repeat. It's a countdown timer that pulses every second from 10 to 0. – rkoth Jul 01 '13 at 19:36

3 Answers3

5

I believe a CountDownLatch will do what you want.

final CountDownLatch latch = new CountDownLatch(10);
int delay = 1000;
int period = 1000;

timerPanel.setText(Long.toString(latch.getCount()));

timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    public void run() {
        latch.countDown();
        timerPanel.setText(Long.toString(latch.getCount()));
    }
}, delay, period);

try {
    latch.await();
}
catch (InterruptedException e) {
    e.printStackTrace();
}

timer.cancel();
Jason Day
  • 8,809
  • 1
  • 41
  • 46
0

You should use Thread.sleep function instead of TimeTask to halt execution.

TimerTask is not meant to halt execution, its like a clock running in background. So for your requirement you should go for Thread.sleep.

Lokesh
  • 7,810
  • 6
  • 48
  • 78
  • The issue with this is that the new thread I've created continuously updates the UI. Sleeping the main thread for the amount of time the new thread seems like a dodgy solution. – rkoth Jul 01 '13 at 19:35
0

Use a Semaphore. Initialize it before declaring the timer task, with 0 permits. In the timer task, use a try/finally block to release the semaphore. In the main thread, acquire the permit from the semaphore.

In your code, join works as specified since it waits for the thread to finish. And no, using a thread for this is not necessary. If you really want to block until a certain time, you don't need a Timer. Get the current time, compute the millis until the future time, and sleep().

Ralf H
  • 1,392
  • 1
  • 9
  • 17