Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Five Ways to Update Fields in a Thread Safe Way: Part 2

DZone's Guide to

Five Ways to Update Fields in a Thread Safe Way: Part 2

The second and last part of detailed tutorials on how to update fields in a thread safe way in Java, along with examples of how they work and how to test them.

· Java Zone
Free Resource

Bitbucket is for the code that takes us to Mars, decodes the human genome, or drives your next car. What will your code do? Get started with Bitbucket today, it's free.

In part one, we looked at the first 3 ways to update a field in a threadsafe way in Java. Here are the 4th and 5th! 

CompareAndSet-Based Atomic Update

When to Use?

Use compareAndSet when the lock in the solution described in part one becomes a bottleneck. Or use it if there exists a ready-made solution, for example, the AtomicInteger as shown below.

Example

The following implements a counter based on Atomic Integer:

public class AtomicIntegerCounter {

private final AtomicInteger i = new AtomicInteger();

public  void addOne()
{
i.incrementAndGet();
}

public int get()
{
return i.get();
}


}

The Atomic Integer uses compareAndSet Internally in the incrementAndGet method:

public final int incrementAndGet() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return next;
        }
    }

How Does it Work?

Again volatile makes changes visible. You are optimistically calculating the new value and only set the calculated value when the value of the field is still the same as at the beginning of the calculation. Thereby you need to make sure that the value is only written if it was not changed by another thread. If your field points to a collection or graph of objects, you must create a copy before your update, similar as copy on write.

How to Test?

We can test this by using a multi-threaded test and adding a wait point in vmlens at the compareAndSet method.

5) Benign Data Race

When to Use?

Only use this when you can sacrifice correctness for performance.

Example

The following example shows a counter used in to switch between different implementations in the class sun.reflect.NativeMethodAccessorImpl:

class  NativeMethodAccessorImpl extends MethodAccessorImpl {
    private Method method;
    private DelegatingMethodAccessorImpl parent;
    private int numInvocations;

    NativeMethodAccessorImpl(Method method) {
        this.method = method;

    }



    public Object invoke(Object obj, Object[] args)
        throws IllegalArgumentException, InvocationTargetException
    {
        if (++numInvocations > ReflectionFactory.inflationThreshold()) {
           MethodAccessorImpl acc = (MethodAccessorImpl)
            new MethodAccessorGenerator().
            generateMethod(method.getDeclaringClass(),
                                 method.getName(),
                                 method.getParameterTypes(),
                                 method.getReturnType(),
                                 method.getExceptionTypes(),
                                 method.getModifiers());
                                 parent.setDelegate(acc);
          }
      return invoke0(method, obj, args);
    }



   ...

}

How Does it Work?

This way of updating the field neither guarantees that changes are visible in other threads, nor guarantees that other threads are not changing the field between an update. But sometimes, as in the above example, you can live with incorrect results for higher performance.

How to Test?

You can test this only with a single threaded test since multiple threads lead to non-deterministic behavior.

Conclusion

Which of the 5 ways you use to update a field in a thread safe way depends on your performance and safety requirements. Independent of which way you use, you should test it. Read more about unit testing multi-threaded software with vmlens and concurrent-junit in a new way to junit test your multithreaded java code. Remember to read the first part if you haven't already!

Bitbucket is the Git solution for professional teams who code with a purpose, not just as a hobby. Get started today, it's free.

Topics:
java ,threads ,fields

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}