1

I have the following piece of code

public String ls() throws IOException, InterruptedException {
    String pwd = getPWD();
    String inodePath = "Upload/Files" + pwd + "inode";

    // Request the inode file first
    Peer.setFileReceivedCheck(false);
    Inode i = new Inode();
    i.requestInode(pwd + "inode");

    boolean fileCheck = Peer.getFileReceivedCheck();
    System.out.println(fileCheck);
    while (fileCheck == false) {
        System.out.println(); // DOES NOT WORK IF THIS LINE IS REMOVED!!
        fileCheck = Peer.getFileReceivedCheck();
    }
    System.out.println(fileCheck);

    return i.readFromInode(inodePath);
}

In the above java method, the fileCheck variable keeps track of when a file is downloaded from the network and becomes true when the file download completes; so that the functions returns when the file download is completed.

The weird problem which I am facing is that if I remove the above line (the one with just a println); the method is stuck in the while loop and does not return even though the file has been downloaded! Any idea as to why this is happening?

EDIT: This is not running in a separate thread. The file download code in another class (Peer.java) is running in a separate. Again, the getter for fileCheck is out of the thread.

gopi1410
  • 6,567
  • 9
  • 41
  • 75
  • Is it possibly checking a non volatile variable from another thread? – kiheru Mar 06 '14 at 10:34
  • Is this running in a threaded environment ? – Brian Agnew Mar 06 '14 at 10:36
  • You say that it's both running threaded, and that it's not. Take a look at the link posted by Burkhard. It's a thread race issue, and would be solved by synchronization (this is what happens with println()), or making the relevant flag volatile. – kiheru Mar 06 '14 at 10:44

2 Answers2

3

Please, in the name of $DEITY, do not use hot polling. Stop. Right now. You are wasting billions of cycles, you will make the whole system less responsive, while you wait for something to come over the network. Use a callback - we are in 2014, it's not rocket science.

That said, repace the contents of the while loop with this:

Object o = new Object();
synchronized(o) {
   fileCheck = Peer.getFileReceivedCheck();
}

What happens is that your check probably just returns a non-volatile field, and the compiler is free to optimize that away - unless your code hits a synchronization point.

Tassos Bassoukos
  • 16,017
  • 2
  • 36
  • 40
  • Great! Had read about `synchronized`, but was not sure how to implement it here; so was trying this workaround. Thanks! – gopi1410 Mar 06 '14 at 10:45
1

Did you try adding a small timeout (100ms), instead of println()?

Taryn
  • 242,637
  • 56
  • 362
  • 405
dkasipovic
  • 5,930
  • 1
  • 19
  • 25