Port of schuchert.wikispaces.com


TddAndConcurrency.Slides.KeepItAwayFromMe

TddAndConcurrency.Slides.KeepItAwayFromMe

Up

Keep It Away From Me

Scope it way down…

A guideline to live by…

Dependent State

Consider the following (incomplete) iterator:

public class IntegerIterator 
	implements Iterator<Integer>, Iterable<Integer> {
    private Integer nextValue = 0;

    public boolean hasNext() {
        return nextValue < 100000;
    }
    public Integer next() {
        return nextValue++;
    }
    public Integer getNextValue() {
        return nextValue;
    }
}


Dependent State+Multi-Threaded

Use this code in a test:

IntegerIterator iterator = new IntegerIterator();

for (Integer value : iterator) {
}

assertEquals(10000, iterator.getNextValue()

What about this use:

public class UseIntegerIterator implements Runnable {
    IntegerIterator iterator;

    public UseIntegerIterator(IntegerIterator iterator) {
        this.iterator = iterator;
    }

    @Override
    public void run() {
        while (iterator.hasNext()) {
            iterator.next();
        }
    }
}

And then in some test somewhere:

IntegerIterator iterator = new IntegerIterator();
Thread t1 = new Thread(new UseIntegerIterator(iterator));
Thread t2 = new Thread(new UseIntegerIterator(iterator));
t1.start();
t2.start();
t1.join();
t2.join();

assertEqual(10000, iterator.getNextValue()); // ?? 

There’s a problem. How can we fix it?

public class UseIntegerIteratorClientBasedLocking 
    implements Runnable {
    public void run() {
        while (true) {
            synchronized (iterator) {
                if (iterator.hasNext())
                    iterator.next();
                else
                    break;
            }
        }
    }
}


Server-Based Locking

The server guards the dependent calls:

package dependent.serverbasedlocking;

public class IntegerIteratorServerLocked {
    private Integer nextValue = 0;

    public synchronized Integer getNextOrNull() {
        if (nextValue < 100000)
            return nextValue++;
        else
            return null;
    }
    public Integer getNextValue() {
        return nextValue;
    }
}

Here’s an updated client that now works:

public void run() {
    while (true) {
        Integer next = iterator.getNextOrNull();
        if (next == null)
            break;
    }
}

Evaluate, between client-based and server-based locking

What if you don’t have control?

Up


Comments

" Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.