DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Effective Engineering Feedback: Software Testing
  • The LLM Selection War Story: Part 2 - The Six LLM Failure Archetypes That Will Wreck Your Production System
  • Agentic Development: My Invisible Dev Team
  • Clean Code in the Age of Copilot: Why Semantics Matter More Than Ever

Trending

  • Getting Started With Agentic Workflows in Java and Quarkus
  • Multi-Scale Feature Learning in CNN and U-Net Architectures
  • Building a Production-Ready AI Agent in 2026: Beyond the Hello World Demo
  • S3 Vectors: How to Build a RAG Without a Vector Database
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Testing, Tools, and Frameworks
  4. Five Ways to Update Fields in a Thread Safe Way: Part 1

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

The first 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.

By 
Thomas Krieger user avatar
Thomas Krieger
·
Aug. 13, 16 · Tutorial
Likes (10)
Comment
Save
Tweet
Share
26.0K Views

Join the DZone community and get the full member experience.

Join For Free

There are five ways to update a field in Java in a thread safe way. But before we start, what do you have to look at? If you access a field from many threads, you must make sure that:

  1. Changes are made visible to all threads
  2. The value is not changed during the update by the other threads
  3. Threads that are reading do not see the inconsistent intermediate state

You can achieve this by one of the following 5 ways:

Volatile Field

When to Use?

You can use a volatile field when you have only one thread updating and many threads reading a single-valued field. Or you can use it when the writing threads do not read the field. You can use it only for single valued fields like boolean or int. If you want to update object graphs or collections, use copy on write, as described below, instead.

Example

The following example code shows a worker thread, which stops processing based on a volatile field. This makes it possible for other threads, like an event dispatching thread, to stop the worker thread.

public class WorkerThread extends Thread 
{ 
    private volatile boolean canceled = false; 
    public void cancelThread() 
    { 
        this.canceled = true; 
    } 
    @Override public void run() 
    { 
       while( ! canceled ) 
       { 
          // Do Some Work 
       } 
    } 
} 

How Does it Work?

Declaring the field volatile makes changes made by one thread visible to all other threads. As a writing thread do not read the value, point b “the value is not changed during the update by the other thread” is fulfilled. Since the field is a single value point c “reading threads do not see inconsistent intermediate state” is also fulfilled.

How to Test?

By using vmlens, an Eclipse plugin to test multi-threaded software and to detect Java race conditions, we can find fields, which should be declared volatile. After declaring the field volatile, we can check in the “order of event” view of vmlens, that the field is correctly read and written:

Order of Events in vmlens

Copy On Write

When to Use?

Use copy on write if you want to update a graph of objects or a collection, and the threads mostly read and only rarely update.

Example

The following shows the add and get Method from java.util.concurrent.CopyOnWriteArrayList:

private transient volatile Object[] array; 
final Object[] getArray() 
{   
  return array; 
} 
public boolean add(E e) 
{ 
   final ReentrantLock lock = this.lock; 
    lock.lock(); 
     try { 
          Object[] elements = getArray(); 
          int len = elements.length; 
          Object[] newElements = Arrays.copyOf(elements, len + 1); 
          newElements[len] = e; 
          setArray(newElements); return true; } 
     finally { 
          lock.unlock(); 
      } 
} 
public E get(int index) 
{ 
   return get(getArray(), index); 
} 

How Does it Work?

Again the volatile declaration makes changes made by one thread visible to the other threads. By using a lock around the updating method, we make sure that the value is not changed during the updating process. Since we copy the data before changing it, reading threads do not see the inconsistent intermediate state.

How to Test?

We can test this by using a multithreaded test and adding a wait point inside vmlens at the read of the field.

Wait Point in vmlens

Lock-Based Atomic Update

When to Use?

Use locks when updates and reads happen equally often. Use it until the lock becomes a bottleneck and you need the more performant solution compareAndSet, as described below.

Example

The following example shows a lock based counter:

public class LockBasedCounter {

private int i = 0;

public synchronized void addOne()
{
i++;
}


public synchronized int get()
{
return i;
}


}

How Does it Work?

The synchronize statements make sure that the changes made by one thread are seen by the other threads. Since only one thread can execute the methods protected by the lock at a given time, the value can not be changed during the update by another thread and the other threads cannot see an intermediate inconsistent state.

How to Test?

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

Wait Point in vmlens

Conclusion

Which of the first 3 of 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. If you have a question or remark please add a comment below, and stay tuned for part 2 tomorrow!

unit test

Published at DZone with permission of Thomas Krieger. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Effective Engineering Feedback: Software Testing
  • The LLM Selection War Story: Part 2 - The Six LLM Failure Archetypes That Will Wreck Your Production System
  • Agentic Development: My Invisible Dev Team
  • Clean Code in the Age of Copilot: Why Semantics Matter More Than Ever

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook