如何在java中对线程正确使用wait()和notify?

如何在java中对线程正确使用wait()和notify?,java,android,multithreading,Java,Android,Multithreading,我正在安卓工作室制作一个2D游戏,几天来我一直在思考一个问题。我想停止我的线重力,这样我的球员就可以跳了。当运动员完成跳跃时,重力线可以继续 我在互联网上搜索了如何将wait()和notify()与syncronised块一起使用。但当我尝试使用它时,我的重力不会停止。如果有人能告诉我如何正确使用这个,我会非常高兴 这是我在场景课上开始跳跃的代码 public void recieveTouch(MotionEvent event) { switch(event.getAction()

我正在安卓工作室制作一个2D游戏,几天来我一直在思考一个问题。我想停止我的线重力,这样我的球员就可以跳了。当运动员完成跳跃时,重力线可以继续

我在互联网上搜索了如何将wait()和notify()与syncronised块一起使用。但当我尝试使用它时,我的重力不会停止。如果有人能告诉我如何正确使用这个,我会非常高兴

这是我在场景课上开始跳跃的代码

public void recieveTouch(MotionEvent event) {

    switch(event.getAction()){
        case MotionEvent.ACTION_DOWN:
            if(player.getPoint().y > 0) {
                playerJump();
            }
    }
}

public void playerJump(){
    playerJump = new Jump(player, this);
    thread = new Thread(playerJump);
    thread.setDaemon(true);
    thread.start();
}
这是我的重力线

public class Gravity implements Runnable {

private Player player;
private GameScene gameScene;

public Gravity (Player player, GameScene gameScene){
    this.player = player;
    this.gameScene = gameScene;
}

@Override
public void run(){
    while(true){

        player.playerMoveDown(3);
        gameScene.update();

        try {
            Thread.sleep(25);
        }
        catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}
这是我的跳线

public class Jump implements Runnable {

private Player player;
private GameScene gameScene;

public Jump (Player player, GameScene gameScene){
    this.player = player;
    this.gameScene = gameScene;
}

@Override
public void run(){
    int eindHoogte = player.getPoint().y - 60;

        while (player.getPoint().y > eindHoogte) {
            player.playerMoveUp(3);
            gameScene.update();

            try {
                Thread.sleep(25);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    }
}

让我给你们一个一般性的回答,这不仅对这个案例有帮助,而且对未来也有帮助,这可以帮助郭台铭作为一个迷你指南。在Java语言中工作时,多线程的基本元素包括

  • 同步块

  • 一个对象,
    lock
    (为了方便和容易理解,可以这样命名),您可以在其上应用同步块来获取监视器

  • wait()
    对象的方法,
    lock

  • notify()
    notifyAll()
    对象的方法,
    lock

  • Thread
    对象,可能是您需要的实现
    Runnable
    intetface的类

  • 注意事项如下

  • 您应该只对当前线程已获取监视器的对象调用wait()、notify()或notifyAll()

  • 1 sleep()是Thread.java的方法,wait()是Object.java的方法 1.2如果已获取锁,sleep()不会放弃锁,而wait()会放弃锁。在获取锁后调用sleep不是强制性的,而至于wait则是强制性的

    1.3也更喜欢notifyAll()而不是notify(),因为notify可能只向任何单个线程发出唤醒并尝试获取锁的信号,而as notifyAll()唤醒所有符合条件的等待线程,并允许竞争获取锁,因此notify对所有线程都有更好的机会

  • 通常一个线程执行一次进程并调用notifyAll()并等待(),直到它再次被通知。此外,如果线程被中断,通常的方法是终止线程。在执行wait方法时,线程会放弃监视器,这也是因为它在调用
    wait
    方法之前调用了
    lock
    对象上的
    notifyAll
    方法,所以所有其他有资格获得锁监视器的线程都会被唤醒。线程调度程序将监视器分配给其中一个线程,它还执行一个命令,调用notifyAll on lock,然后调用wait on lock。现在,第二个线程也进入等待状态,以便重新激活监视器,同时其他线程获取监视器,整个过程将继续,直到我们不中断所有线程为止

  • 你可以从我为另一个问题所写的答案中找到这样一个模型的例子


    只需确保在使用android时,您不会从除主GUI线程以外的任何其他线程修改主GUI,如果您希望这样做,请使用处理程序

    让我给您一个一般性的答案,这不仅对本例有帮助,而且对将来也有帮助。这可以作为一个迷你指南。在Java语言中工作时,多线程的基本元素包括

  • 同步块

  • 一个对象,
    lock
    (为了方便和容易理解,可以这样命名),您可以在其上应用同步块来获取监视器

  • wait()
    对象的方法,
    lock

  • notify()
    notifyAll()
    对象的方法,
    lock

  • Thread
    对象,可能是您需要的实现
    Runnable
    intetface的类

  • 注意事项如下

  • 您应该只对当前线程已获取监视器的对象调用wait()、notify()或notifyAll()

  • 1 sleep()是Thread.java的方法,wait()是Object.java的方法 1.2如果已获取锁,sleep()不会放弃锁,而wait()会放弃锁。在获取锁后调用sleep不是强制性的,而至于wait则是强制性的

    1.3也更喜欢notifyAll()而不是notify(),因为notify可能只向任何单个线程发出唤醒并尝试获取锁的信号,而as notifyAll()唤醒所有符合条件的等待线程,并允许竞争获取锁,因此notify对所有线程都有更好的机会

  • 通常一个线程执行一次进程并调用notifyAll()并等待(),直到它再次被通知。此外,如果线程被中断,通常的方法是终止线程。在执行wait方法时,线程会放弃监视器,这也是因为它在调用
    wait
    方法之前调用了
    lock
    对象上的
    notifyAll
    方法,所以所有其他有资格获得锁监视器的线程都会被唤醒。线程调度程序将监视器分配给其中一个线程,它还执行一个命令,调用notifyAll on lock,然后调用wait on lock。现在,第二个线程也进入等待状态,以便重新激活监视器,同时其他线程获取监视器,整个过程将继续,直到我们不中断所有线程为止

  • 你可以从我为另一个问题所写的答案中找到这样一个模型的例子


    只需确保在使用android时,您不会从主GUI线程以外的任何其他线程修改主GUI,如果您希望这样做,请使用处理程序

    假设您正在将相同的播放器对象传递给Jump和Gravity类,您可以在播放器上同步,并为Jump complete操作维护一个标志

    这将确保当玩家表现出色时
        public class Jump implements Runnable {
    
        private Player player;
        private GameScene gameScene;
    
        public Jump (Player player, GameScene gameScene){
            this.player = player;
            this.gameScene = gameScene;
        }
    
        @Override
        public void run(){
            int eindHoogte = player.getPoint().y - 60;
    
            while (player.getPoint().y > eindHoogte) {
                    player.playerMoveUp(3);
                    gameScene.update();
    
                    try {
                        Thread.sleep(25);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
            }
    
            synchronized(player){
    
                // acts as a signal to gravity thread to start processing the gravity operation
                player.setJumpComplete(true);
            }
    
        }
    
    }
    
    
        public class Gravity implements Runnable {
    
            private Player player;
            private GameScene gameScene;
    
            public Gravity (Player player, GameScene gameScene){
                this.player = player;
                this.gameScene = gameScene;
            }
    
            @Override
            public void run(){
    
    
    
                while(true){
    
                    synchronized (player) {
    
                        // if player has completed the jump then process the gravity operation else just wait for jump to complete
                        if(player.isJumpComplete()){
                            player.playerMoveDown(3);
                            gameScene.update();
    
                            // reset the jump flag and wait for the next jump operation to complete
                            player.setJumpComplete(false);
                        }
    
                    }
    
                    try {
                        Thread.sleep(25);
                    }
                    catch (InterruptedException e){
                        e.printStackTrace();
                    }
                }
            }
    
    interface Effect {
       method Point getMotion(duration);
       method Boolean isCompleted();
    }
    
    class Jump implements Effect {
      ///...
    }
    
    class sceneObject {  
    
      synchronized  List<Effect> movementEffects;
    
      Point position;
    
      void move(Point);
    
      void addEffect(Effect);
    
      void removeEfects(Class);
    
       void Point getTotalMotion(duration) {
           Point result;
           for each effect in movementEffects {
                  result += effect. getMotion(this, duration);
                  if effect.isCompleted() {
                         removeEffect(effect)
                  }
           }
           return result;
        }
        void applyMotion(duration) {
             move(getTotalMotion(duration))
        }
    }
    
    class player extends SceneObject {
    
       Effect gravity = new Gravity(3);
    
       Player () {
               addEffect(gravity);
       }
    
        void jump() {
               addEffect(new Jump)
        }
    
        void walkLeft() {
               stopWalking();
               addEffect(new Walk(-3))
        }
    
        void stopWalking() {
               removeEffects(Walk.class)
       }
    }
    
    class EffectsThread {
          void run() {
              While (...)  {
                    timeSinceLastIteration = ... ;
    
                    for each item in scene {
                          item.applyMotion(timeSinceLastIteration);
                    }
                    //sleep
               }
          }
    }