多线程-不唤醒基于回合的游戏中的其他线程。爪哇

时间:2018-11-04 14:29:53

标签: java multithreading wait notify

我是多线程的新手,但我被要求制作游戏。我希望每个玩家都同时轮流,但不要让一个玩家在另一个玩家转1圈的时间内转4圈。

我的run()方法当前看起来像:

public synchronized void run(){  
        while (!gameWon) {
            takeTurn();
            hasPlayerWon();
            playersTurnTaken += 1;
            System.out.println(Thread.currentThread().getName() + " has taken their turn");
            if (playersTurnTaken != n) {
                try {
                    wait();
                } catch (InterruptedException e) {}
            } else {
                playersTurnTaken = 0;
                notifyAll();
            }
        }
    }

这是在一个名为player的嵌套类内,其中父类为CradGame,而CardGame则具有playersTurnTaken属性。我使用这个变量来找出每个玩家何时轮到自己将其声明为易失性变量(我认为这就是您应该定义的变量)。

但是程序的输出是这样的:

Thread-3 has taken their turn
Thread-1 has taken their turn
Thread-2 has taken their turn
Thread-0 has taken their turn
Thread-0 has taken their turn

然后我猜测所有线程都在等待,因为程序没有结束。

为什么他们在Thread-0完成第一个转弯后不醒来?任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

很简单。这里的问题是线程需要一个接一个地执行。

我想您已经从单个类创建了所有玩家实例,并且他们都在读取共享变量(易失性)。

要注意这一点,才能起作用。  -请使用Atomic变量代替volatile。挥发时一般都可以    是一个布尔变量。

  • 在播放器对象的每个实例中传递此变量以及一个int变量。

    AtmomicInteger sharedVariable = new AtomicInteger(1);
    Player player1 = new Player(sharedResource, countToCheck);
    
  • 现在假设要启动玩家1和2,您必须在下面进行。

    Player player1 = new Player(sharedResource, 1);
    Player player2 = new Player(sharedResource, 2);
    
  • 每个播放器运行方法都使用countToCheck检查sharedVariable计数。一旦 那些等于run方法完成执行并更新sharedVariable 计数为+1。

  • player1可以检查一下sharedResource值是否等于1。如果是的话 执行,然后将sharedResource值更新为2。 执行run方法,因为它正在等待sahredResource值为2。 等等,您创建的所有播放器线程将继续执行。