在俄罗斯方块游戏中正确使用 wait()/notify()
我正在为 Android 编写一个类似俄罗斯方块的游戏,并且正在尝试实现“实时部分”。我有一些似乎有效的东西,但我想确保我的实现是正确的。
我想要的是:
形状以固定速率下降(假设每次形状的 y 递减时我想等待 n 毫秒)
玩家可以随时放下形状,等待 n 毫秒的计时器必须立即中断,并仅针对下一个形状重新启动
当形状掉落或形状无法再下降时,游戏会在创建另一个形状之前等待 m 毫秒
系统必须能够随时停止线程
我正在做的事情如下(系统可以使用 interrupt()
停止线程):
class TetrisThread extends Thread {
private int n = 3000; // for testing purposes, in the real game n will be smaller ;)
private int m = 1000;
@Override
public void run() {
doDraw();
while(!interrupted())
{
try {
synchronized (this) {
wait(n);
}
doPhysics();
doDraw();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
// This method is the one which will drop the shape, it is called from another thread
synchronized public boolean onTouch([…]) {
[…]
// The shape has to be dropped
dropShape();
notify();
[…]
}
private void doPhysics() throws InterruptedException {
[…]
// The shape cannot go down or has been dropped
sleep(m);
createNewShape();
[…]
}
}
特别是 synchronized(this) { wait( n); }
看起来很有趣,因为如果我理解正确的话,这将锁定 this
并立即释放它。
但是 wait()
需要在 synchronized(this)
块中使用(为什么?)并且我无法同步整个 run()
方法,因为如果我在 sleep(m)
调用期间尝试删除三倍的形状,那么接下来的三个形状将自动删除(这不是我想要的)。
您认为这正确吗?
您有什么更正、建议或评论吗?
谢谢 :-)
I’m writing a Tetris-like game for Android and I’m trying to implement the “real-time part”. I have something which seems to work, but I want to be sure that my implementation is correct.
What I want is:
The shapes are going down at a fixed rate (say that I want to wait n milliseconds each time the y of the shape is decremented)
The player can drop the shape at any time and the timer waiting for the n milliseconds must then be immediately interrupted and start again only for the next shape
When the shape is droped or when the shape cannot go down anymore, the game waits m milliseconds before creating another shape
The system have to be able to stop the thread at any time
What I am doing is the following (the system can stop the thread with interrupt()
):
class TetrisThread extends Thread {
private int n = 3000; // for testing purposes, in the real game n will be smaller ;)
private int m = 1000;
@Override
public void run() {
doDraw();
while(!interrupted())
{
try {
synchronized (this) {
wait(n);
}
doPhysics();
doDraw();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
// This method is the one which will drop the shape, it is called from another thread
synchronized public boolean onTouch([…]) {
[…]
// The shape has to be dropped
dropShape();
notify();
[…]
}
private void doPhysics() throws InterruptedException {
[…]
// The shape cannot go down or has been dropped
sleep(m);
createNewShape();
[…]
}
}
In particular, the part synchronized(this) { wait(n); }
looks funny because if I understand correctly this will take a lock on this
and release it immediately.
But wait()
requires to be used in a synchronized(this)
block (why?) and I cannot either synchronize the whole run()
method, because then if I try to drop three times the shape during the sleep(m)
call, then the three next shapes will be automatically dropped (which is not what I want).
Does this seem correct to you?
Do you have any correction, advice, or remark?
Thank you :-)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
wait()
方法用于使当前运行的线程等待调用wait()
的对象调用notify()
(在本例中这)。synchronized(this)
部分需要确保当时只有一个线程访问this
。您无法同步整个 run() 方法,因为 run() 来自父(Thread)类,并且父类在声明中没有使用同步。
我不知道如何解决你的其他问题,因为我不明白你的程序现在是如何工作的。
The
wait()
method is used to make the current running thread to wait the object invokingwait()
invokenotify()
(in this case this). Thesynchronized(this)
part needed to make sure only one thread at that time accessingthis
.You can't synchronize the whole run() method, because the run() is from the parent (Thread) class and the parent didn't use synchonized in the declaration.
I don't know how to solve your other problem because I don't get how your program works right now.