4

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.

7
  • How is Driver defined? Commented May 22, 2018 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? Commented May 22, 2018 at 20:25
  • public String setMyVariable() This method should be static if you want to call the way you are calling. stackoverflow.com/questions/21204589/… Commented May 22, 2018 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. Commented May 22, 2018 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? Commented May 22, 2018 at 20:33

6 Answers 6

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();
Sign up to request clarification or add additional context in comments.

4 Comments

This also do not compile.
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"
You need to fix import statements in your class to use your Driver class instead of java.sql.Driver
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.
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

1 Comment

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.
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.

1 Comment

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.
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");
    }
}

Comments

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

Comments

0

If you want to share data between all threads use static variable which is the solution suggested in this thread.

To share data between parent and child -

  • If you are using Java 12+ use SharedData class.

  • If using < Java 11. Create your own SharedString class . Here is an example -

public class DataSharingExample {
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            SharedString sharedString = new SharedString();

            Thread parentThread = new Thread(() -> {
                sharedString.setString("Hello from parent thread " + Thread.currentThread().getId());

                Thread childThread = new Thread(() -> {
                    String data = sharedString.getString();
                    System.out.println("Child thread " + Thread.currentThread().getId() + " received: " + data);
                });
                childThread.start();
                try {
                    childThread.join(); // Wait for the child thread to complete
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                sharedString.setString("Modified data from parent thread " + Thread.currentThread().getId());
                String modifiedData = sharedString.getString();
                System.out.println("Parent thread " + Thread.currentThread().getId() + " received modified data: " + modifiedData);
            });

            parentThread.start();
            try {
                parentThread.join(); // Wait for the parent thread to complete
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class SharedString {
    private String string;

    public synchronized void setString(String string) {
        this.string = string;
    }

    public synchronized String getString() {
        return string;
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.