Domanda

I'm reading this book, (O'Reillys Java Threads 3rd ed., which for now has very bad explanations), and I have encountered this code:

//in RandomCharacterGenerator class
public void run( ) {
    while (!isInterrupted()) {
            nextCharacter( );
            try {

                Thread.sleep(getPauseTime( ));

            } catch (InterruptedException ie) {
                return;
            }
    }
}

And the following explanation (producer is the instance of upper class in the main thread):

producer.interrupt( );

If the main thread executes this statement while the RandomCharacterGenerator thread is sleeping, the RandomCharacterGenerator thread gets the interrupted exception and immediately returns from the run() method. Otherwise, when the character-feeding thread next gets to the top of its loop, it sees that the interrupted flag has been set and returns from its run() method then. Either way, the random character generator thread completes its task.

Note that this technique does not completely eliminate the possibility that we sleep for some amount of time after the thread is asked to stop. It's possible for the main thread to call the interrupt() method just after the RandomCharacterGenerator has called the isInterrupted() method. The character-reading thread still executes the sleep() method, which won't be interrupted (since the main thread has already completed the interrupt() method). This is another example of a race condition that we solve in the next chapter. Since the race condition in this case is benign (it just means we sleep one more time than we'd like), this is sufficient for our purposes.

Second paragraph is completely unclear to me. My first question is: How can we sleep one more cycle? If we interrupt the thread when sleeping it goes out of run, if we interrupt before sleep it will interrupt sleep as soon as it starts sleeping (I tested that, and I think that's true? Am I right), if we interrupt after sleep it will brake the loop.

Second question: In this example (this is the whole code from the book) is the check in loop completely unnecessary, and can it stand while (true) with the same outcome, so that first paragraph about the top of the loop is complete nonsense?

È stato utile?

Soluzione

The book is wrong. Interrupting the thread before it sleeps will make the sleep() method throw an InterruptedException immediately.

Quote from Java Concurrency in Practice:

A good way to think about interruption is that it does not actually interrupt a running thread; it just requests that the thread interrupt itself at the next convenient opportunity. (These opportunities are called cancellation points.) Some methods, such as wait, sleep, and join, take such requests seriously, throwing an exception when they receive an interrupt request or encounter an already set interrupt status upon entry.

(emphasis mine)

In this particular example, using while(true) would lead to the same effect. But in other cases, if the loop never calls an interruptible method, or if you want to exit as soon as possible, you'll have to regularly check if the thread is interrupted to be able to detect the interruption.

Altri suggerimenti

The book believes you will spend an extra cycle in the following case:

RandomCharacterGenerator -> isInterrupted = false;

Main -> interrupt()

RandomCharacterGenerator -> runs through code
RandomCharacterGenerator -> sleeps
RandomCharacterGenerator -> isInterrupted = true

It actually will interrupt on the sleep, but the thing it is trying to get at that is important is that you may run through the code one more time after calling interrupt()

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top