简体   繁体   English

在两个线程中使用相同的变量,但我不知道为什么它们不会在Java中更新

[英]Using the same variables in two threads, but I don't know why they won't update in Java

I would like to start off by saying that I know there are similar questions to this. 我想先说我知道有类似的问题。 I did some searching, and I DID find some information. 我做了一些搜索,我发现了一些信息。 Unfortunately, the solutions did not help me. 不幸的是,解决方案对我没有帮助。 I do not know why. 我不知道为什么。 This is why I ask this question. 这就是我问这个问题的原因。

I have two Threads I am working with in Java. 我有两个我正在使用Java的线程。 I have four classes that are related to this. 我有四个与此相关的课程。 The first class is the class with the 'main' method in it. 第一个类是带有'main'方法的类。 It sets up and starts all the Threads. 它设置并启动所有线程。 Here is how I start and declare the Threads: 这是我如何开始并声明线程:

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();

The second class contains all the global variables. 第二个类包含所有全局变量。 This class is called 'GlobalVariables'. 这个类叫做'GlobalVariables'。 GlobalVariables: GlobalVariables:

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

The other class, which is called 'DeliverMessage' is set up like this. 另一个名为“DeliverMessage”的类就是这样设置的。 This is one of the classes I have my problem with. 这是我遇到问题的课程之一。 DeliverMessage: 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);
      }
    }
  }

The last class I am having trouble with is called 'Timing'. 我遇到麻烦的最后一堂课叫做'Timing'。 I would like it to be able to change the boolean variables in order to control when the messages are delivered. 我希望它能够更改布尔变量,以便控制何时传递消息。 Here it is: 这里是:

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;
  }
}

I have looked into using 'volatile'. 我已经研究过使用'volatile'了。 I did not find that worked. 我没有发现那有效。 I tried declaring the variables in 'GlobalVariables' like this 'public volatile boolean proceed;'. 我尝试在'GlobalVariables'中声明变量,就像'public volatile boolean proceed;'一样。 I tried changing the variable, but the 'DeliverMessage' class did not register that change. 我尝试更改变量,但'DeliverMessage'类没有注册该更改。 I also tried doing the same thing with 'static'. 我也试过用'静态'做同样的事情。 That did not work either. 那也行不通。 The variables seem to change in the 'Timing' class, but they do not link to the SAME variables in the 'DeliverMessage' class. 变量似乎在'Timing'类中发生了变化,但它们没有链接到'DeliverMessage'类中的SAME变量。

Please let me know what I should do. 请告诉我应该怎么做。 Thanks in advance, ~Rane 提前谢谢,~Rane

EDIT: Thank you! 编辑:谢谢! I have a couple really quick clarifications though. 我有几个非常快速的澄清。 1) Do I declare the boolean variables as both 'static' and 'volatile'? 1)我是否将布尔变量声明为'static'和'volatile'? 2) How do I refer to the variables in the 'DeliverMessage' and 'Timing' classes? 2)如何引用'DeliverMessage'和'Timing'类中的变量?

Your two classes, Timing and DeliverMessage each have their own unique instance of GlobalVariables, so changing the state of one GlobalVariables object will have no effect on the other GlobalVariables object. 您的两个类Timing和DeliverMessage都有自己唯一的GlobalVariables实例,因此更改一个GlobalVariables对象的状态对其他GlobalVariables对象没有影响。 If you want them to share the same GlobalVariables instance, then give them the same instance. 如果你希望它们共享相同的GlobalVariables实例,然后他们相同的实例。

ie, give them both a 即,给他们两个

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

method and pass the same GlobalVariables instance into both Timing and DeliverMessage classes. 方法并将相同的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();

And yes, make the GlobalVariables' boolean variables volatile, but that's still not your major issue. 是的,使GlobalVariables的布尔变量易变,但这仍然不是你的主要问题。

Note: another option is to pass the GlobalVariables instance into your class constructors. 注意:另一个选项是将GlobalVariables实例传递给类构造函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM