0

I'm now trying to add an update checking module into my program. The method is processing a website for update informations. But in some situations the website is not accessable, and the program stops checking in 0.5 seconds. To make this possible, I wrote these code:

int[] lock = new int[0];
boolean fileListGot = false;

Thread downloadFile = new Thread() {
    public void run() {
        synchronized (lock) {
            fileList = HttpFetcher.fetch("http://*****/****");
            fileListGot = true;
            lock.notify();
        }
    }
};

synchronized (lock) {
    downloadFile.start();
    lock.wait(500);
}

return fileListGot;

But the program doesn't stop after 0.5 seconds. What the wrong with the program? And how to use Object.wait(long)?

Chaofan
  • 93
  • 1
  • 4

2 Answers2

1

Read the Object.notify javadocs - the important part being "The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object. "

The main thread acquires the monitor of lock. It starts the worker thread. The worker thread attempts to gain lock's monitor, but cannot. The main thread then calls lock.wait(500) and so loses the monitor. The worker thread then gains the monitor and proceeds. If the download is still going on after 500ms, wait returns and the main thread attempts to gain the monitor, but it is still owned the worker thread.

You don't need to hold the monitor when downloading the file, only when mutating the shared variables - try this instead

public void run() {
    T temp = HttpFetcher.fetch("http://*****/****");
    synchronized (lock) {
        fileList = temp;
        fileListGot = true;
        lock.notify();
    }
}

where T is the appropriate type for fileList

Pete Kirkham
  • 48,893
  • 5
  • 92
  • 171
  • You're absolutely right! But I do not agree with your solution. Although it will cause the method to return after 500ms, it does not abort the fetch operation itself. So I'd suggest using something like that: http://jcip.net.s3-website-us-east-1.amazonaws.com/listings/TimedRun.java – isnot2bad Sep 29 '13 at 14:42
0

You enter synchronized block then start a thread. The thread's run tries to enter synchronized block and waits forever because you have already taken the same lock from another thread.

Move downloadFile.start() away from synchronized block.

Alexander Kulyakhtin
  • 47,782
  • 38
  • 107
  • 158