java - 在俄罗斯方 block 游戏中正确使用 wait()/notify()

标签 java android synchronization tetris


我正在为 Android 编写一款类似俄罗斯方 block 的游戏,并且正在尝试实现“实时部分”。我有一些似乎有效的东西,但我想确保我的实现是正确的。

我想要的是:

  • 形状以固定速率下降(假设每次形状的 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) block 中使用(为什么?)并且我无法同步整个 run() 方法,因为如果我在 sleep(m) 调用期间尝试删除该形状的三倍,那么接下来的三个形状将自动删除(这不是我想要的)。

您认为这正确吗?
您有什么更正、建议或评论吗?

谢谢:-)

最佳答案

wait()方法用于使当前运行的线程等待调用wait()的对象调用notify() (在这种情况下是这样的)。 synchronized(this) 部分需要确保当时只有一个线程访问 this

您无法同步整个 run() 方法,因为 run() 来自父(Thread)类,并且父类在声明中没有使用 synchronized。

我不知道如何解决你的其他问题,因为我不明白你的程序现在是如何工作的。

关于java - 在俄罗斯方 block 游戏中正确使用 wait()/notify(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5608776/

相关文章:

Java io丑陋的try-finally block

java - 处理本地化的字符串包含单个 TextView 中的链接

c# - 等待任何线程完成,而不是全部

java - 同步块(synchronized block)内的同步块(synchronized block)

java - 等待使用 Display::asyncExec() 提交到 SWT UI 线程的所有 Runnable 完成

java volatile与java链表一起使用

java - 我什么时候应该使用 'while loop' ?

android - 背景音乐会是一个单独的后台进程吗?

android - 我怎样才能拥有具有不同 TextView 和 Spinner 文本颜色的全局主题?

Java - 多用户应用程序中的同步