Reputation: 2040
I have a thread which repeats an action each second (shooting):
long lasttime;
Creature owner;
public Attacker(Creature actor)
{
super("Attacker - "+actor.getClass().getSimpleName());
lasttime=System.currentTimeMillis();
owner=actor;
owner.lockedon=true;
}
@Override
public void run() {
super.run();
while(!owner.dead && owner.lockedon)
{
List pl=TVS.getGameScreen().projectiles;
synchronized (pl)
{
//here
long curtime=System.currentTimeMillis();
if(curtime-lasttime>1000)
{
owner.attack();
lasttime=curtime;
}
}
}
}
But when the main program thread slows down, this thread executes faster than main and shooting becomes too frequent relatively to the main thread. What should I do?
Upvotes: 0
Views: 102
Reputation: 1109
I'd rather use Timers as they're easier to maintain and tends to be more accurate:
Timer shooterTimer = new Timer();
shooterTimer.scheduleAtFixedRate(
new TimerTask() {
@Override
public void run() {
if (!owner.dead && owner.lockedon) {
List pl = TVS.getGameScreen().projectiles;
synchronized (pl) {
onwer.attack();
}
}
}
},
0, // Start the timer now
1000); // Execute the task every second
Upvotes: 0
Reputation: 533880
You are busy waiting, holding a lock which is likely to either consume a lot of CPU, or lock out other threads trying to use the same lock. I suggest something like
while(!owner.dead && owner.lockedon) {
List pl=TVS.getGameScreen().projectiles;
long curtime=System.currentTimeMillis();
long remaining = 1000 - (curtime-lasttime);
if(remaining <= 0) {
synchronized (pl) { // only lock when needed.
owner.attack();
lasttime=curtime;
}
} else {
// when not doing something useful, give up the CPU to another thread.
Thread.sleep(remaining);
}
}
Upvotes: 2