views:

196

answers:

5

I want to implement the usual cooperative mechanism for canceling a thread. However the java memory model was only fixed in JDK5 while I'm in a pre-JDK5 environment. I understand, this means that doing something like this, as espoused in SCIP, will not be correct.

class Worker implements Runnable
{
    private volatile boolean _canceled;

    public void cancel() { _canceled = true; }

    public void run() {
        while( ! _canceled )
        {
            // do my shit
        }
    }
}

I'm thinking of using an AtomicBoolean to encapsulate the _canceled variable. Any other alternatives ? Thanks Stackoverflow.

A: 

I don't think AtomicBoolean was available before Java 5 either. What about synchronizing on a private Boolean field?

Martin
What's wrong is the part of the question: "cheapest performance hit". Depending on which pre-JDK5 version is in use, synchronization can be comparatively expensive.
Eddie
+3  A: 

AtomicBoolean was also added in JDK5, so this isn't available unless you are using the backport. However, yes, the atomic class from the backport may be the best choice, as you know it was written by people who are versed in what works in each version of the JVM virtual machine spec.

Eddie
I will have a look at the backport code. Thanks
Jacques René Mesrine
+2  A: 

The util.concurrent package by Doug Lea (the precursor to the java.util.concurrent stuff) might help.

TofuBeer
+1: I've never seen that before...*bookmark*.
Anthony Cuozzo
+3  A: 

If I understand the FAQ correctly, this is not a problem in the old memory model which allowed reordering of volatile fields. In their example, the old model would allow "x" to be either 0 or 42 based on the JVM. The rule of thumb is that reordering should always be a performance gain by the compiler/cpu, but not be visiable to the programmer. The old model broke that rule.

Your example should not suffer that visability problem and would work

Ben Manes
That's how I read it, too. If the cancel() method in the example set some other (non-volatile) field before setting _canceled, then the run() method would not have a guarantee of seeing that new value when it exits the loop. But as written, the example would work.
Marty Lamb
What if I told you I'm running in Java 1.1
Jacques René Mesrine
Ben Manes
+1  A: 

IIRC, very old Sun JREs didn't implement volatile at all. Sensibly attempted, the old JMM allows volatiles to be used in this kind of way (about the only way they can be used). I understand Sun 1.4 JRE actually implements the 1.5 JMM, with any differences considered bugs.

Tom Hawtin - tackline