JavaPong-timer线程睡眠仍然运行函数

JavaPong-timer线程睡眠仍然运行函数,java,timer,Java,Timer,我在爪哇打乒乓球 如果球出界,pause设置为true: if (ball.getX() <= 0) { score2++; pause = true; } if (ball.getX() >= this.getWidth()-ballWidth) { score1++; pause = true; } Ball类AutoMove()函数: public void a

我在爪哇打乒乓球

如果球出界,
pause
设置为
true

    if (ball.getX() <= 0) {
        score2++;   
        pause = true;       
    }
    if (ball.getX() >= this.getWidth()-ballWidth) {
        score1++;
        pause = true;
    }
Ball类AutoMove()函数:

public void autoMove(double velX, double velY) {
    xLoc = this.getX()+velX;    
    yLoc = this.getY()+velY;    
}
它做到了这一切。。。它休眠,暂停设置为false,等等。。。但是当球停了1秒后(在屏幕中部复位),它跳转到游戏面板的远端,它告诉我,当线程“睡觉”时,<代码>球。代码>仍在更新坐标

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


谢谢

当此线程处于睡眠状态时,保证不会调用
autoMove
。但是,如果不看代码,我敢打赌autoMove是根据实时变化来移动球的。这将使球在暂停结束后显示为跳跃,然后再次调用autoMove

您需要将autoMove更改为基于相对时间,或者需要更改它使用的时间变量并减去暂停时间。

指令

timer.scheduleAtFixedRate(new TimerTask() {...}, initial, 100 );
在睡眠1秒期间,向计时器队列添加10次自动移动

固定费率的日程安排是正确的,但你不必做任何事情来代替睡眠

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

按照执行日志进行睡眠

首先,该计划:

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]
1369769673294:线程[Timer-0,5,main]

1369769674308:Thread[Timer-0,5,main]将很好地看到正在更改暂停位置的完整代码

你怎么知道它是在睡觉的时候发生的?你能添加带有时间戳的记录器吗?但我要试试看

如果暂停是在另一个线程中设置的,那么您需要在它上进行同步,如果您声明它为volatile,这将是一个好主意。在此方法中进行同步,并在其他任何位置设置暂停

private volatile Boolean pause = false;
//...
//make a setter and getter for pause
synchronized ( pause    ){
    return  pause ;    
}

synchronized ( pause    ){
    return  pause = newPauseValue;    
}

永远不要在EDT中睡觉,尝试使用
ball.autoMove()
?什么是
EDT
?谢谢您确定
宽度
高度
设置正确吗?
EDT
是事件调度线程。阅读更多:这不仅仅是猜测。我们知道事实上,它不是在睡觉的时候叫它。有了这个保证,这是唯一的解释真的吗?哇!我该如何解决这个问题?@Growler我想你只要使用
scheduleWithFixedDelay
就可以了。什么时候调用timer()?如果重复调用,则可以使用@Aubin建议的方法,并使变量volatle在所有线程中读取相同的值。你还没有显示哪个线程暂停是真的(我猜是UI线程?@Aubin我不明白为什么我不能使用
thread.sleep()
,然后。。。什么时候可以使用它呢?不要把睡眠和调度混在一起,第一个暂停线程,第二个保证每xx个延迟就调用一个方法。就像跑进一架飞机,坐下来放松,即使你什么都不做,飞机也会飞…只使用setter和getter来读取和更改pause的值。我在上面展示的是唯一被更改的位置
pause
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]
private volatile Boolean pause = false;
//...
//make a setter and getter for pause
synchronized ( pause    ){
    return  pause ;    
}

synchronized ( pause    ){
    return  pause = newPauseValue;    
}