0

I am sending a some json to a php page from my java application which echos "finished" if successful. The json and php are working great. I am trying to pass a string to a thread and then change the value of the string to the echo from the php in the thread, and when the Thread is finished I want to use an if statement to determine if the URL connection was successfully completed... which it is I just can't get the value of the string from the Thread.

here is my code:

main.java

final String line = "unfinished";
Thread iURL = new instrURL(line, jsonArray);
iURL.start();

while(iURL.isAlive())
{
    System.out.println("In wait loop");
}


System.out.println(line);

if(line.trim() == "finished")
{
    System.out.println("Made it to finished");
}
else
{
    System.out.println("Did not make it to finished");
}

instrURL.java

public class instrURL extends Thread{

String line;
String jsonArray;

public instrURL(String line, String jsonArray)
{
    this.line = line;
    this.jsonArray = jsonArray;
}

public void run()
{

    try 
    {
        URL url = new URL("http://fake.php?jsonArray="+URLEncoder.encode(jsonArray, "UTF-8"));

        URLConnection conn = url.openConnection();

        BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));

        line = rd.readLine();

        System.out.println(line);

        rd.close();

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }

    }

the console:

In wait while loop
In wait while loop
...
...
...
In wait while loop
finished
In wait while loop
In wait while loop
In wait while loop
unfinished
Did not make it to finished

As you can see from the console the Thread gets the finished, but once outside of the Thread the strings value is still unfinished.

Any help would be greatly appreciated.

user908759
  • 1,355
  • 8
  • 26
  • 48
  • 5
    Regarding `== "finished"`: [how-do-i-compare-strings-in-java](http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java) – Pshemo Apr 29 '14 at 21:16
  • I don't see anywhere where you set _any_ string to `"finished"`, so why do you think `line.trim().equals("finished")` would ever be `true` even after you fix the `==` problem? – ajb Apr 29 '14 at 21:20
  • 2
    Java is pass by value, so you cannot update the value of `line` unless you explicitly assign a new value of. But you cannot since `line` is declared as `final`. – Luiggi Mendoza Apr 29 '14 at 21:21
  • Sorry changed String line to line = rd.readLine(); – user908759 Apr 29 '14 at 21:25
  • 1
    @OP Still, `if(line.trim() == "finished")` will never be true. – azurefrog Apr 29 '14 at 21:26

2 Answers2

2

You have at least four different String reference variables with the name line in your process, and updates to one won't be reflected in the other ones, which is why your program doesn't behave as expected:

  1. final String line = "unfinished"; in main.java - looks like a local variable on the stack
  2. instrURL(String line, - a paramter to the instrURL constructor
  3. instrURL.line a member in the instrURL class
  4. String line; a local in the run() method in instrURL

All of these are distinct references, so assigning to one will not affect any of the others. Even beyond that, I don't see any assignments at all to any of the flavors of line in the instrURL class.

Generally speaking you should use established inter-thread communication methods such as Future, or shared statics under a lock, but probably the closest thing to what you want is to declare a static volatile String line somewhere, and refer to it in both main and your thread class, and remove all other copies of line.

BeeOnRope
  • 60,350
  • 16
  • 207
  • 386
  • after changing final to public static and changing my build path I was able to get it to work. Thanks! – user908759 Apr 29 '14 at 22:11
  • A `public static` member? That's poor design, on two counts. If you don't want to use a `Future`, the best design would be to have your main create a *mutable* object with a `String` field, and use that object reference when constructing the `Thread`, to establish that as an object that the main and the thread will share. – ajb Apr 29 '14 at 23:33
  • Poor design is a bit besides the point here, I think - given the number of errors in the example (it doesn't compile). I mentioned already the best practice of using `Future`, but I included also the idea of a static variable to at least show the minimal working example to illustrate why the existing code didn't share anything. – BeeOnRope Apr 30 '14 at 18:49
1

Java compare string with equals method not with ==

if(null!line && line.trim().equals("finished"))
    {
        System.out.println("Made it to finished");
    }

Inside run method you are not reading data from buffered reader and not changing the value of line, that's why you are getting same value as "unfinished", you need to read data like this

 String currentLine
    while ((currentLine = br.readLine()) != null) {
        System.out.println(sCurrentLine);
    }

after reading data from stream , set value in line string as

line="finished";
Asif Bhutto
  • 3,916
  • 1
  • 24
  • 21