Java Pong - 定时器线程睡眠仍然运行功能 [英] Java Pong - timer thread sleep still runs function

查看:21
本文介绍了Java Pong - 定时器线程睡眠仍然运行功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 Java 打乒乓球

I'm making pong in java

如果球出界,pause设置为true:

    if (ball.getX() <= 0) {
        score2++;   
        pause = true;       
    }
    if (ball.getX() >= this.getWidth()-ballWidth) {
        score1++;
        pause = true;
    }

哪个应该让计时器休眠...线程休眠 1000 毫秒后,暂停将设置为 false 并且球应该继续移动 (ball.autoMove()):

which should sleep the timer... after the thread has slept for 1000ms, pause will be set to false and the ball should continue moving (ball.autoMove()):

public void timer() {
    int initialDelay = 1000;

    timer.scheduleAtFixedRate(new TimerTask() {
        public void run() {
            if (pause) {
                try {   
                    ball.reset(width/2, height/2);
                    Thread.sleep(1000);     
                    pause = false;                      
                } 
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            ball.autoMove(velocityX, velocityY);    
            collisionCheck();           
        }
    }, initialDelay, 100);  
}

球类 AutoMove() 函数:

Ball Class AutoMove() function:

public void autoMove(double velX, double velY) {
    xLoc = this.getX()+velX;    
    yLoc = this.getY()+velY;    
}

它完成所有这些...它休眠,暂停设置为 false,等等...但是当球在暂停 1 秒后重置(在屏幕中间重置...),它跳转到游戏面板的远端,它告诉我当线程休眠"时,ball.autoMove(velocityX, velocityY); 仍在更新坐标.

It does all of that... it sleeps, pause is set to false, etc... but when the ball is reset (reset in the middle of the screen...) after it pauses for 1 second, it jumps to the far side of the game panel which tells me that while the thread was "sleeping", ball.autoMove(velocityX, velocityY); was still updating the coordinates.

为什么会这样?不应该运行吗?

Why is this happening? Shouldn't that not be run?

谢谢!

推荐答案

使用说明

timer.scheduleAtFixedRate(new TimerTask() {...}, initial, 100 );

在 1 秒的睡眠期间将 10 次 autoMove 添加到计时器队列中.

add 10 occurrences of autoMove to the timer queue during the sleep of 1 second.

固定费率的安排是对的,但除了睡觉你什么都不做.

The scheduling at fixed rate is right but you have to do nothing in place of sleeping.

将计数器设置为 10 并在每次调用方法时递减它,当它达到零时,继续以正常方式(与暂停"方式相反).

Set a counter to 10 and decrement it each time the method is called and when it reach zero, keep going on the normal way (in opposition to the "pause" way).

timer.scheduleAtFixedRate(new TimerTask() {
   public void run() {
      if( pauseCount == 10 ) {
         ball.reset(width/2, height/2);
      }
      if( pauseCount > 0 ) {
         --pauseCount;
      }
      else {
         ball.autoMove( velocityX, velocityY );
         collisionCheck();
      }
   }
}, initialDelay, 100 );

按照执行日志睡眠.

首先是程序:

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

public class SO {

   static boolean isTrue = true;

   public static void main( String[] args ) {
      new Timer().scheduleAtFixedRate( new TimerTask() {
         @Override public void run() {
            System.out.println(
               System.currentTimeMillis() + ": " + Thread.currentThread());
            try{
               if( isTrue ) {
                  TimeUnit.SECONDS.sleep( 1 );
                  isTrue = false;
               }
            }
            catch( InterruptedException e ){
               e.printStackTrace();
            }
         }
      }, 0, 100 );
   }
}

还有日志,观察时间:

1369769673294: Thread[Timer-0,5,main]
1369769674308: Thread[Timer-0,5,main] <-- #1 at 308
1369769674308: Thread[Timer-0,5,main] <-- #2 at 308
1369769674308: Thread[Timer-0,5,main]
1369769674308: Thread[Timer-0,5,main]
1369769674308: Thread[Timer-0,5,main]
1369769674308: Thread[Timer-0,5,main]
1369769674308: Thread[Timer-0,5,main]
1369769674308: Thread[Timer-0,5,main]
1369769674308: Thread[Timer-0,5,main]
1369769674308: Thread[Timer-0,5,main] <-- #10 at 308, queued during the sleep
1369769674402: Thread[Timer-0,5,main]
1369769674496: Thread[Timer-0,5,main]
1369769674605: Thread[Timer-0,5,main]
1369769674699: Thread[Timer-0,5,main]
1369769674808: Thread[Timer-0,5,main]
1369769674901: Thread[Timer-0,5,main]
1369769674995: Thread[Timer-0,5,main]

我们观察到激活就像排队一样,但实际上 Timer 类只有一个线程.它是模拟事件队列的逻辑,java.util.Timer 很清楚:

We observe the activation are like queued but in fact, the class Timer has only one thread. It's its logic which simulate the queue of events, the documentation of java.util.Timer is clear:

在固定速率执行中,每次执行都是相对于初始执​​行的预定执行时间.如果执行是由于任何原因(例如垃圾收集或其他背景活动),两个或多个执行将快速连续发生跟上来."从长远来看,执行频率将是正好是指定周期的倒数(假设系统Object.wait(long) 底层的时钟是准确的).由于以上,如果预定的第一次是过去,那么任何错过"的处决将被安排为立即赶上"执行.

In fixed-rate execution, each execution is scheduled relative to the scheduled execution time of the initial execution. If an execution is delayed for any reason (such as garbage collection or other background activity), two or more executions will occur in rapid succession to "catch up." In the long run, the frequency of execution will be exactly the reciprocal of the specified period (assuming the system clock underlying Object.wait(long) is accurate). As a consequence of the above, if the scheduled first time is in the past, then any "missed" executions will be scheduled for immediate "catch up" execution.

这篇关于Java Pong - 定时器线程睡眠仍然运行功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆