2

I'm having trouble accessing data in my main thread from my new thread. I can do this just fine without threading by just using the main class getters/setters. But when I try to launch a new thread I can no longer do so.

Main Class:

public class Driver extends Application{

//create socket handlers
Runnable myNewThread = new workerThread();

//variables
private String lastMessage = "";

//getters and setters
public String setMyVariable() {
    this.MyVariable = MyVariable;
}

//main
public static void main(String[] args) {
    //launch threads
    new Thread(myNewThread).start();
}

NewThread Class:

public class workerThread implements Runnable{

public void run() {
    Driver.setMyVariable("test");
}

I get the error "Cannot resolve symbol 'setMyVariable'" in my workerThread class. As far as I can tell it's because my workerThread thread doesn't know what instance of Driver to refer to (there is only one instance, but it doesn't know that). Could someone help me understand what I'm missing? I've seen examples of declaring the new class within a function of the main class, but I'm trying to avoid this in the interest of code organization as my worker thread is going to be a bit large.

nyi
  • 3,123
  • 4
  • 22
  • 45
Mr. Phil
  • 61
  • 1
  • 2
  • 9
  • How is Driver defined? – jspcal May 22 '18 at 20:21
  • @jspcal It's just defined as a class in the first section of code. It isn't defined in the workerThread. Perhaps I need to somehow? – Mr. Phil May 22 '18 at 20:25
  • `public String setMyVariable()` This method should be static if you want to call the way you are calling. https://stackoverflow.com/questions/21204589/static-vs-instance-variables-difference – Md Johirul Islam May 22 '18 at 20:26
  • 3
    I guess you is trying to run before learn to walk. IMHO you should to learn the basic concepts from Java before try to play with threads. – Duloren May 22 '18 at 20:28
  • Why do you have `new workerThread(this.getClass());`? You can just pass `this` which is an instance of you class. `getClass` gets the base class. This extends `Application`, is this a javafx app? – matt May 22 '18 at 20:33
  • @MdJohirulIslam I tried making it static but it didn't resolve the "cannot resolve symbol" issue. I still have the same problem as before. – Mr. Phil May 22 '18 at 20:36
  • @Duloren I understand the basic concepts of Java. I am now learning the basic concepts of threading. My understanding of which was not furthered by your comment. – Mr. Phil May 22 '18 at 21:17

5 Answers5

2

You are calling setMyVariable("test") as if it is a static method. You need to pass an instance of Driver class to instance of workerThread.

public class workerThread implements Runnable {
  private Driver driver;

  public workerThread(Driver d, Class c) {
    this.driver = d;
    //do whatever you are doing with existing Classs parameter
  }

  public void run() {
    driver.setMyVariable("test");
  }

And also make changes to Driver class

public class Driver extends Application{

  //create socket handlers
  Runnable myNewThread = new workerThread(this, this.getClass());

 //variables
 private String lastMessage = "";

 //getters and setters
 public String setMyVariable() {
   this.MyVariable = MyVariable;
 }

 //main
 public static void main(String[] args) {
   //launch threads
   new Thread(new Driver().myNewThread).start();
 }
}

UPDATE:

And because myNewThread variable is also non-static you have to do the following in Driver.main() to be able to compile:

new Thread(new Driver().myNewThread).start();
Ivan
  • 8,508
  • 2
  • 19
  • 30
  • This also do not compile. – Duloren May 22 '18 at 20:29
  • Thanks for your answer. I am unable to compile with the error "workerThread (java.sql.Driver) cannot be applied to Driver" at the line "Runnable myNewThread = new workerThread(this, this.getClass());" It seems that "this" does not match the type that is being expected by the workerThread with "Driver d" – Mr. Phil May 22 '18 at 20:47
  • 1
    You need to fix `import` statements in your class to use your `Driver` class instead of `java.sql.Driver` – Ivan May 22 '18 at 20:48
  • Ah I see! For anyone else with a similar issue, simply deleting the `import java.sql.Driver` import at the top of my workerThread class solved the issue for me. – Mr. Phil May 22 '18 at 21:14
0

When you call a function from a class directly the system expects it to be a static one (Like you do here: Driver.setMyVariable("test");) But your function is not static and I think it shouldn't be as you variable isn't static as well. If you wish to work with separate objects you need to instantiate them first with it's constructor

Anwera97
  • 1
  • 2
  • I see why it needs to be static the way that I'm calling it. Because I only have one instance of the Driver class I believe that making it static should be fine. However, doing so didn't resolve the "cannot resolve symbol" issue. – Mr. Phil May 22 '18 at 20:35
0

You're attempting to call a static method without defining your method as static. Change your method to:

public static String setMyVariable() {
    this.MyVariable = MyVariable;
}

Then, you'll have to change the definition of MyVariable to be static as well.

I'm not sure, though, you understand the consequences of what you're doing. Creating a static variable will allow you to share your data between threads as there will be one instance of the variable across all instances of your class, but this is a potentially dangerous thing to do if you don't really understand static variables.

Make sure you do your homework on this before making this decision.

Md Johirul Islam
  • 5,042
  • 4
  • 23
  • 56
Thom
  • 14,013
  • 25
  • 105
  • 185
  • I see why it needs to be static the way that I'm calling it. Because I only have one instance of the Driver class I believe that making it static should be fine. However, doing so didn't resolve the "cannot resolve symbol" issue. – Mr. Phil May 22 '18 at 20:34
0

Don't make it static. Pass an instance of your object.

//Runnable myNewThread = new workerThread(this.getClass());
Runnable myNewThread = new workerThread(this);

Then your workerThread should have a constructor.

public class workerThread implements Runnable{
    Driver driver;
    public workerThread(Driver driver){
        this.driver=driver;
    }
    public void run() {
        driver.setMyVariable("test");
    }
}
matt
  • 10,892
  • 3
  • 22
  • 34
0
public class Driver extends Application{

   public static Driver instance = new Driver();

   //create socket handlers
   public static Runnable myNewThread = new workerThread();

   //variables
   private String lastMessage = "";
   private static String MyVariable = "";

   //getters and setters
   public static String setMyVariable(String MyVariable) {
      instance.MyVariable = MyVariable;
      return MyVariable;
  }

  //main
  public static void main(String[] args) {
  //launch threads
      new Thread(myNewThread).start();
  }
}