【问题标题】:Using the same variables in two threads, but I don't know why they won't update in Java在两个线程中使用相同的变量,但我不知道为什么它们不会在 Java 中更新
【发布时间】:2014-09-27 02:24:25
【问题描述】:

我想首先说我知道有类似的问题。我做了一些搜索,我确实找到了一些信息。不幸的是,这些解决方案对我没有帮助。我不知道为什么。这就是我问这个问题的原因。

我有两个在 Java 中使用的线程。我有四个与此相关的课程。第一个类是其中包含“main”方法的类。它设置并启动所有线程。以下是我开始和声明线程的方式:

Thread thread1 = new Thread(){
  public void run(){
    DeliverMessage deliverMess = new DeliverMessage();
    deliverMess.deliver();
  }
}

Thread thread2 = new Thread(){
  public void run(){
    Timing time = new Timing();
    time.controlTime();
  }
}
thread1.start();
thread2.start();

第二个类包含所有的全局变量。此类称为“GlobalVariables”。 全局变量:

public class GlobalVariables(){
  //Variables
  public boolean proceed;
  public boolean doubleCheck;
}

另一个名为“DeliverMessage”的类是这样设置的。这是我遇到问题的课程之一。 传递消息:

public class DeliverMessage(){
  //Variables
  String mess1 = "Hello";
  String mess2 = "How are you?";
  String mess3 = "Goodbye";
  //Setup
  GlobalVariables global = new GlobalVariables();

  public void deliver(){
    while(true){
      if(global.proceed){
        System.out.println(mess1);
      }
      if(global.doubleCheck){
        System.out.println(mess2);
        System.out.println(mess3);
      }
    }
  }

我遇到的最后一门课叫做“Timing”。我希望它能够更改布尔变量以控制何时传递消息。这里是:

public class Timing(){
  //Setup
  GlobalVariables global = new GlobalVariables();
  public void controlTime(){
    try {
        TimeUnit.SECONDS.sleep(4);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    global.proceed = true;
    try {
        TimeUnit.SECONDS.sleep(16);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    global.doubleCheck = true;
  }
}

我已经研究过使用“易失性”。我没有发现那行得通。我尝试在“GlobalVariables”中声明变量,例如“public volatile boolean continue;”。我尝试更改变量,但“DeliverMessage”类没有注册该更改。我也尝试用“静态”做同样的事情。那也没有用。 'Timing' 类中的变量似乎发生了变化,但它们没有链接到 'DeliverMessage' 类中的 SAME 变量。

请让我知道我应该做什么。提前致谢, ~兰恩

编辑:谢谢!不过,我有几个非常快速的澄清。 1)我是否将布尔变量声明为“静态”和“易失性”? 2) 如何引用“DeliverMessage”和“Timing”类中的变量?

【问题讨论】:

    标签: java multithreading static volatile


    【解决方案1】:

    您的两个类 Timing 和 DeliverMessage 都有自己的唯一 GlobalVariables 实例,因此更改一个 GlobalVariables 对象的状态不会影响另一个 GlobalVariables 对象。如果您希望他们共享同一个 GlobalVariables 实例,则他们同一个实例。

    即,给他们两个

    public void setGlobalVariables(GlobalVariables global) {
       this.global = global;
    }
    

    方法并将相同的 GlobalVariables 实例传递给 Timing 和 DeliverMessage 类。

    final GlobalVariables global = new GlobalVariables();
    Thread thread1 = new Thread(){
      public void run(){
        DeliverMessage deliverMess = new DeliverMessage();
        deliverMess.setGlobalVariables(global);
        deliverMess.deliver();
      }
    }
    
    Thread thread2 = new Thread(){
      public void run(){
        Timing time = new Timing();
        time.setGlobalVariables(global);
        time.controlTime();
      }
    }
    thread1.start();
    thread2.start();
    

    是的,将 GlobalVariables 的布尔变量设为 volatile,但这仍然不是您的主要问题。

    注意:另一种选择是将 GlobalVariables 实例传递给您的类构造函数。

    【讨论】:

    • 我是否将布尔变量声明为“静态”和“易失性”?另外,如何引用“GlobalVariables”类中的变量?
    • @Rane:如果你将变量设为静态,一只小狗会在某处被杀死,所以请不要这样做。要设置和访问它们,请使用 getter 和 setter。
    • @HovercraftFullOfEels 是否使字段成为静态的选择与是否将相同的字段公开或通过访问器方法发布它们的选择无关。当您写static 时,他们会杀死一只小狗。当你未能进入非决赛场地private时,他们会杀死一只小猫
    猜你喜欢
    • 2023-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-23
    • 1970-01-01
    相关资源
    最近更新 更多