0

I've hit my head against a wall again today, and after so much time testing and trying to understand why, I decided to ask here if anyone knows what's happening.

So I've got this class inheriting a class inheriting from jpanel:

public class InputPw extends InputPan {
    private String input = "";
    private static boolean typing = false;

    public InputPw() {
        super();
        input = "";
        typing = true;
    }
    public void nPressed() {
        typing = false;
        System.out.println("back");
    }
    public void aPressed() {
    // one of many methods like this one called from main() and only 
    //values (string always) to input.
    input += "A";
    }
}

the method calling this code:

    InputPan input = new InputPw();
    pw_clear = input.getInput(); 
    System.out.println(pw_clear + "PASSWORD");

so far so good, no problem.

public String getInput() {
    // TODO Auto-generated method stub
    typing = true;
    String str = "";
    while(isTyping()) { //isTyping() returns the value 
    of typing (boolean)
        if (!input.equals("")) str += input;
        //System.out.println(typing);
        input = "";
    }
    System.out.println("str " + str);
    return str;
 }

this code confirms me that n was pressed, and typing was set to false, but nothing happens (infinite loop).

Now the fun part: just uncommenting the line system.out.println(typing); I get confirmation that N is pressed, I get the println("str") to actually print, but str itself is empty. So printing my boolean helps me get out of the loop somehow.

And, finally, what got it working:

public String getInput() {
    // TODO Auto-generated method stub
    typing = true;
    String str = "";
    while(isTyping()) { 
        if (!input.equals("")) str += input;
        //System.out.println(isTyping());
        input = "";
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    System.out.println(" str" + str);
    return str;
}

So it looks like adding a sleep solved the problem, but why? and why does my program behave differently if I println some values (aka the while(boolean) never checking boolean unless boolean is printed), but still doesn't register my inputs in the str?

And how do I avoid that in the future?

Thank you!

Yogso
  • 11
  • 1
  • 2
    It sounds similar to this problem: https://stackoverflow.com/questions/25425130/loop-doesnt-see-changed-value-without-a-print-statement – GBlodgett Oct 14 '18 at 23:31
  • Interesting read! Makes sense about the print part, but what about the str being empty? – Yogso Oct 14 '18 at 23:38
  • 1
    It looks a synchronization problem to me... Either printing the variable was delaying the process by a few ms, or the jvm used other optimazations when this variable was used. It looks like neither "typing" nor "input" are used in a thread safe way... So the root of the problem is the use of a non thread-safe code in a multi-threading environment. – Alkis Mavridis Oct 14 '18 at 23:40
  • 1
    Thread safe sounds like an important concept. I'll read more into that and see if it answers my questions. Thank you! – Yogso Oct 14 '18 at 23:51

0 Answers0