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;
}