在Java中,有没有办法让一个类知道另一个类中的变量在运行时发生了变化?

在Java中,有没有办法让一个类知道另一个类中的变量在运行时发生了变化?,java,Java,我试图编写一个代码,其中主类(带有main方法的类)需要播放音乐,而另一个类中名为“running”的变量为true。但是,如果在运行时变量变为false,则主类中的变量仍然保持true。下面是我的代码片段 public static void main(String[] args) { Game game = new Game("Geometry Dash", 700, 600); game.start(); System.out.println(Game.ru

我试图编写一个代码,其中主类(带有main方法的类)需要播放音乐,而另一个类中名为“running”的变量为true。但是,如果在运行时变量变为false,则主类中的变量仍然保持true。下面是我的代码片段

public static void main(String[] args) {

    Game game = new Game("Geometry Dash", 700, 600);

    game.start();


    System.out.println(Game.running);
    do  {
            GameState.runMusic();
    }while(Game.running);


}

代码真的不重要。相反,我试图找到一种方法,让我的主类意识到另一个类中的某个变量变为false(因此发生了更改)。

问题是,在设置标志之前,您希望播放音乐

while (flag) {
     PlayMusic();
}
这会有问题,因为即使将标志设置为false,它也不会工作,直到
PlayMusic()
返回。因此,你不仅需要一种方法来接收中断,还需要一种方法来停止音乐。因此,在不使用线程的情况下,一种方法是设置计时器,让计时器每隔一段时间(可能是100毫秒)继续检查
标志,然后发出停止音乐的信号

    Timer timer = new Timer(0, (ae)-> {
             if (!flag) {
                MusicOff();
                timer.stop();
             }
        });

    timer.setDelay(100);
    timer.start();
事实上,您甚至不需要while循环。这完全取决于如何实现

你如何设置国旗取决于你自己

有没有办法让一个类知道另一个类中的变量在运行时发生了变化

课堂不是活动的东西。。。但线程是。所以我假设你实际上是指执行
main
方法的线程

(此外,除非您谈论的是
静态
变量,否则该变量属于对象(类的实例),而不是类。)


一个线程(只有)两种方式可以“知道”另一个线程更改了一个变量

  • 线程可以重复测试变量。这就是您的代码当前正在执行的操作。对此有一些警告;见下文

  • 线程可以等待另一个线程告诉它变量已更改。这可以使用
    对象.wait
    对象.notify
    对象.notifyAll
    方法完成

  • 重复测试一个变量可能会很昂贵,尤其是在测试间隔很小的情况下。所以你(通常)可能会这样写:

    while (!someObject.flag) {
        // so somthing that doesn't take a long time
        Thread.sleep(INTERVAL_MILLIS);
    }
    
    但问题是:

    • 如果
      间隔\u MILLIS
      太小,这可能仍然太贵,并且
    • 如果
      间隔_MILLIS
      太大,则在检测到变化之前可能会有明显的延迟
    第二个问题是,上述方法甚至可能不起作用。为了保证线程在测试时看到对
    标志的更改,您的代码在读写
    标志时需要同步,或者
    标志
    需要声明为
    易失性
    。(或使用
    AtomicBoolean
    作为标志。)

    因此,使用
    wait
    notify
    通常是更好的选择。这就是它看起来的样子:

     public class MyClass {
    
         private boolean flag = false;    
    
         /**
          Wait for flag to become `true`.
          */
         public synchronized void await() {
             while (!this.flag) {
                 this.wait();
             }
         }
    
         public synchronized void setFlag(boolean value) {
             this.flag = value;
             this.notifyAll();
         }
     }
    

    或者,您可以使用
    倒计时闩锁
    循环载波

    您应该实现回调或使用设计模式来观察在运行时更改的变量。比如说,

    //In game class
    public class Game{
       private GameStateListener gameStateListener;
    
    
    
       public void setGameStateListener(GameStateListener gameStateListener){
          this.gameStateListener = gameStateListener;
       }
       public void stop(){
         if(this.gameStateListener != null){
               this.gameStateListener.onStateChange(false);
         }
       }
    
    
       public interface GameStateListener{
            void onStateChange(boolean running);
       }
    }
    
    //In your main class or whenever you would like to start and stop music
    
    game.setGameStateListener(new GameStateListener() {
          void onStateChange(boolean running){
              //these code block will be executed whenever event is triggered from Game class.
              if(!running){
                //if you implement this to stop game button
                GameState.stopMusic();
              }else{
                //if you implement this to start game button.
                GameState.runMusic();
              }
          }
    });
    

    另一方面,如果您有多个无法跟踪所有事件的事件,例如开始游戏、用户评分、发送请求等。您可能希望实现其他注释中提到的设计模式,例如观察者模式。

    Java中没有内置的方法来实现这一点,但是你应该看看观察者模式,你需要看看“观察者模式”。您可能还想看看
    volatile
    实现这一点的方法不止一种,还有无数种。我会删除另一个类的单词needs。但是有一整套的原语可以做到这一点,但是需要查找的几个关键字是并发性和并行性。您可以通过定义Java接口并让您的“观察者”类实现它来“滚动您自己的”。更好的是,您可以使用标准Java类“Java.util.Observable”: