0

I would like to run a TimerTask in a Timer while some condition is true.

The code I have for the timed event is as follows:

public Double timedAttack(Fighter target){
    TimerTask task = new TimerTask() {
        public void run() {
            attack(target);
        }
    };
    Timer timer = new Timer();
    long speed =  Math.round(getStats().getSpeed() * 1000);
    timer.schedule(task, speed);
    return stats.getDamage();
}

This creates a timer, where a fighter must wait it's attack time to execute it's attack against a target. The target will equally be executing this method on the fighter.

The problem I am having is in the method below:

public boolean battle(Fighter target){
    while(target.isAlive() && this.isAlive()){
        if(isAlive()) {
            timedAttack(target);
        } else {
            break;
        }
        if(target.isAlive()) {
            Double damageDelt = target.timedAttack(this);
            target.getStats().increaseFitness(damageDelt);
        } else {
           break;
        }
    }
    printBattleResult(target);
    return battleResult(target);
}

The problem is that, the while loop is constantly creating new timers, which eventually results in a stack overflow.

I would like for it to check if the TimerTask has been executed before running the method timedAttack. I've tried passing back reference to the TimerTask, but there is not built in method to check if the Timer is finished.

I've also tried implementing my own TimerTask which includes an isDone variable to check if the TimerTask is completed, but this has not helped much either since I can't gain access to the TimerTask until after the timedAttack method is executed (at which point a new timer is made anyway)

I also considered created an instance variable of the TimerTask so that I can access its methods / properties at anytime. But since it needs a target passed into it to be attacked, this has also proved to not be very helpful.

If anyone has any helpful suggestions on how to do this, I would greatly appreciate it.

I'm not very familiar with threads / threading, so any advice is helpful.

This is not a duplicate of how to stop a TimerTask, as i'm familiar with how this is done. My question is more specific to creating a TimerTask for each iteration of a loop, if the previous TimerTask has already completed.

Jonathan Hinds
  • 305
  • 2
  • 13
  • 1
    You appear to be misusing the loop as the Timer/TimerTask are supposed to be used *in place of a loop*, meaning you're not yet clear in how to use this tool. Why not put the while condition within the TimerTask itself, and only perform the action of the condition is the desired condition. – Hovercraft Full Of Eels Jan 08 '19 at 00:26
  • If I put the while condition within the TimerTask itself, all iterations of the while loop are executed after the timer goes through one time. The goal is that, until either the fighter, or the target is dead a timedAttack takes place. So that essentially, they are taking turns attacking each other with a timed attack. @HovercraftFullOfEels – Jonathan Hinds Jan 08 '19 at 00:44
  • 1
    No one said to put the while loop within the timer task, and again the timer is to be used *in place of a loop*. Please read a tutorial on how to use Timer and TimerTask since, again, your assumptions on their use are incorrect. Please check out [some of these links](https://www.google.com/search?q=java+how+to+use+a+timer+timertask) for more on this – Hovercraft Full Of Eels Jan 08 '19 at 01:01
  • @HovercraftFullOfEels thanks for the tough love. While googling the matter didn't do much for me, I found in the java documentation how do this using scheduleAtFixedRate, I'll post the answer shortly after doing more test. – Jonathan Hinds Jan 08 '19 at 02:02
  • It's frustrating, I know, but this sort of thing has been asked and answered on this site too many times to count. You just need to get over that potential energy barrier of understanding that the Timer ***replaces*** the loop. Once you understand that, this **will** work. – Hovercraft Full Of Eels Jan 08 '19 at 02:06
  • @HovercraftFullOfEels I wanted to clarify that me thanking you wasn't sarcastic. I see what you were saying, thank you. – Jonathan Hinds Jan 08 '19 at 02:18
  • While the dup may not be the best we could find: 1) Hovercraft's comments basically provide you with the information that you need, 2) if you are angling for someone to write you a tutorial on how to use TimerTask, that's not what StackOverflow is for (many such tutorials articles *already exist*), and 3) if you are asking us to rewrite your code to use `TimerTask` properly, that would be Too Broad. – Stephen C Jan 08 '19 at 03:20
  • FWIW: the obvious solution would be to have a single `Timer` and a single `TimerTask` that you schedule (once) to run repeatedly using `scheduleAtFixedRate`. The `TimerTask` then cancels *itself* when the condition is no longer true. Read the javadoc for `cancel()`. – Stephen C Jan 08 '19 at 03:25
  • @StephenC, your last comment is what I ended up doing. I haven't had time to post the answer but will be doing so shortly. I never asked for anyone to write a tutorial, nor rewrite my code - I was simply looking for advice, I got it and it seems to have worked. – Jonathan Hinds Jan 08 '19 at 13:53

0 Answers0