Fundamentals 6 min read

Why i++ Is Not Thread‑Safe: A Hands‑On Demo with vmlens

This article demonstrates how the non‑atomic i++ operation can cause race conditions in Java by using the vmlens tool to visualize thread interleavings, providing sample test code, Maven configuration, and an analysis of the resulting report.

FunTester
FunTester
FunTester
Why i++ Is Not Thread‑Safe: A Hands‑On Demo with vmlens

In the previous post we noted that the expression i++ is not thread‑safe because it consists of separate read‑modify‑write steps, but we did not show exactly how the race occurs. This article uses the open‑source tool vmlens to illustrate the problem.

Test code :

public class TestCounter {
    private volatile int i = 0;

    @Interleave
    public void increment() {
        i++;
    }

    @Test
    public void testUpdate() throws InterruptedException {
        Thread first = new Thread(() -> increment());
        Thread second = new Thread(() -> increment());
        first.start();
        second.start();
        first.join();
        second.join();
    }

    @After
    public void checkResult() {
        assertEquals(2, i);
    }
}

The pom.xml must contain the vmlens plugin and its dependencies. The essential parts are shown below:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.vmlens</groupId>
    <artifactId>examples</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    
    <pluginRepositories>
        <pluginRepository>
            <id>vmlens</id>
            <url>http://vmlens.com/download</url>
        </pluginRepository>
    </pluginRepositories>
    
    <dependencies>
        <dependency>
            <groupId>com.vmlens</groupId>
            <artifactId>annotation</artifactId>
            <version>1.0.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.vmlens</groupId>
                <artifactId>interleave</artifactId>
                <version>1.0.4</version>
                <configuration>
                    <includes>
                        <include>com.vmlens.examples.doNotCombine.TestCounter</include>
                    </includes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Running the test with the vmlens plugin produces a report (see image) that shows both threads reading the initial value 0, each computing 0 + 1, and then both writing back 1. Consequently the final assertion that i == 2 fails, demonstrating the race condition.

vmlens report screenshot
vmlens report screenshot

About vmlens : it is a Java multithreading testing tool that can monitor all accesses to shared memory locations or monitors, insert waits to explore different interleavings, and automatically detect data races and deadlocks. By visualizing how threads interact with shared state, developers can reduce the amount of shared data and the need for synchronization.

The author, Thomas, summarizes his motivation: "I created vmlens to enable systematic, reproducible testing of multithreaded Java code, helping developers write concurrent software that is verified by tests."

author Thomas
author Thomas
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Javaconcurrencythread safetymultithreadingvmlens
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.