2

This looks like the simplest runnable I could imagine

public class StringShower implements Runnable{

    private volatile boolean running = true;
    private String text;

    public StringShower(String text){
        this.text = text;
    }

    @Override
    public void run() {
        while (running) {
            try {
                System.out.println("Current text" + text);
                if(text != null){
                    showText(text); 
                }
                Thread.sleep((long) 1000);
            } catch (Exception e) {
                running = false;
            }
        }       
    }

    private void showText(String text2) {
        System.out.println("Current Text " + text2);

    }
    public void stopRunning() {
        this.running = false;
    }

That is the class starting it

public class ChangeString {

  private static String changeme;

    public static void main(String[] args) {
      Thread thread1 = new Thread(new StringShower(changeme));
      thread1.start();

      changeme = "changed";
  }
}

After reading many examples, I can't still figure out why the String inside the thread is never updated. Can anyone explain why?

user3732793
  • 1,699
  • 4
  • 24
  • 53

4 Answers4

4

changeme = "changed"; changes what String changeme references in the main method, it does not change what reference text in your StringShower instance is referencing.

Since a String is also immutable and cannot be changed, you could wrap the string with another class that gets and sets a String, and pass a reference of this wrapper class.

If you do make such a wrapper class, make sure the get and set are synchronized so that each thread sees what the latest reference refers to when querying.

NESPowerGlove
  • 5,496
  • 17
  • 28
  • tried the other suggestions also but putting the string to a wrapper class actually did work straightforward. thanks a lot – user3732793 Apr 19 '15 at 19:36
2

In addition to what NESPowerGlove said. String is Immutable. You can never change the value of the string. Whenever you try to update it or set it to something you are either creating a new object or just referencing an existing string.

Carlos Bribiescas
  • 4,197
  • 9
  • 35
  • 66
0

StringShower holds a reference to null in its text field. How?

changeMe is initialized to null by default and that's what you're passing to StringShower and assigning to text. You then update the reference that changeMe points to, but this has no effect on what text points to (which is still null).

If you want to manipulate the text field, consider using a setter. And / or make sure the text you pass to the StringShower constructor has been assigned.

async
  • 1,537
  • 11
  • 28
0

You initialize text with the value of a reference which points to the same object as changeme does. Later you change the reference saved in changeme but this does not affect text because you did not change the object they point to but saved a new reference in changeme.

Java is pass-by-value. See Is Java "pass-by-reference" or "pass-by-value"? for a more in-depth explanation.

Community
  • 1
  • 1
Robert Kühne
  • 898
  • 1
  • 12
  • 33