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
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Recurrent Workflows With Cloud Native Dapr Jobs
  • Avoiding If-Else: Advanced Approaches and Alternatives
  • Dust: Open-Source Actors for Java
  • Redefining Java Object Equality

Trending

  • Automatic Code Transformation With OpenRewrite
  • How to Convert XLS to XLSX in Java
  • A Complete Guide to Modern AI Developer Tools
  • Mastering Advanced Traffic Management in Multi-Cloud Kubernetes: Scaling With Multiple Istio Ingress Gateways
  1. DZone
  2. Coding
  3. Java
  4. Java Concurrency: Visibility and Synchronized

Java Concurrency: Visibility and Synchronized

In this post, gain insight into variable visibility between two threads and what happens when we change a variable that is shared.

By 
Emmanouil Gkatziouras user avatar
Emmanouil Gkatziouras
DZone Core CORE ·
Aug. 28, 24 · Code Snippet
Likes (6)
Comment
Save
Tweet
Share
8.3K Views

Join the DZone community and get the full member experience.

Join For Free

Previously, we examined the happens before guarantee in Java. This guarantee gives us confidence when we write multithreaded programs with regard to the re-ordering of statements that can happen. In this post, we shall focus on variable visibility between two threads and what happens when we change a variable that is shared.

Code Examination

Let’s examine the following code snippet:

Java
 
import java.util.Date;
 
public class UnSynchronizedCountDown {
    private int number = Integer.MAX_VALUE;
 
    public Thread countDownUntilAsync(final int threshold) {
        return new Thread(() -> {
            while (number>threshold) {
                number--;
                System.out.println("Decreased "+number +" at "+ new Date());
            }
        });
    }
 
    private void waitUntilThresholdReached(int threshold) {
        while (number>threshold) {
        }
    }
 
    public static void main(String[] args) {
        int threshold = 2125840327;
 
        UnSynchronizedCountDown unSynchronizedCountDown = new UnSynchronizedCountDown();
        unSynchronizedCountDown.countDownUntilAsync(threshold).start();
 
        unSynchronizedCountDown.waitUntilThresholdReached(threshold);
        System.out.println("Threshold reached at "+new Date());
    }
}


This is a bad piece of code: two threads operate on the same variable number without any synchronization. Now the code will likely run forever! Regardless of when the countDown thread reaches the goal, the main thread will not pick the new value which is below the threshold. This is because the changes made to the number variable have not been made visible to the main thread. So it’s not only about synchronizing and issuing thread-safe operations but also ensuring that the changes a thread has made are visible.

Visibility and Synchronized

Intrinsic locking in Java guarantees that one thread can see the changes of another thread. So when we use synchronized the changes of a thread become visible to the other thread that has stumbled on the synchronized block.

Let’s change our example and showcase this:

Java
 
package com.gkatzioura.concurrency.visibility;
 
 
public class SynchronizedCountDown {
    private int number = Integer.MAX_VALUE;
    private String message = "Nothing changed";
    private static final Object lock = new Object();
 
    private int getNumber() {
        synchronized (lock) {
            return number;
        }
    }
 
    public Thread countDownUntilAsync(final int threshold) {
        return new Thread(() -> {
            message = "Count down until "+threshold;
            while (number>threshold) {
                synchronized (lock) {
                    number--;
                    if(number<=threshold) {
                    }
                }
            }
        });
    }
 
    private void waitUntilThresholdReached(int threshold) {
        while (getNumber()>threshold) {
        }
    }
 
    public static void main(String[] args) {
        int threshold = 2147270516;
 
        SynchronizedCountDown synchronizedCountDown = new SynchronizedCountDown();
        synchronizedCountDown.countDownUntilAsync(threshold).start();
        System.out.println(synchronizedCountDown.message);
 
        synchronizedCountDown.waitUntilThresholdReached(threshold);
        System.out.println(synchronizedCountDown.message);
    }
}


Access to the number variable is protected by a lock. Also modifying the variable is synchronized using the same lock.

Eventually, the program will terminate as expected since we will reach the threshold. Every time we enter the synchronized block the changes made by the countdown thread will be visible to the main thread. This applies not only to the variables involved on a synchronized block but also to the variables that were visible to the countdown thread. Thus although the message variable was not inside any synchronized block at the end of the program its altered value got publicized, thus saw the right value printed.

Java (programming language) Lock (computer science) Data Types

Published at DZone with permission of Emmanouil Gkatziouras, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Recurrent Workflows With Cloud Native Dapr Jobs
  • Avoiding If-Else: Advanced Approaches and Alternatives
  • Dust: Open-Source Actors for Java
  • Redefining Java Object Equality

Partner Resources

×

Comments
Oops! Something Went Wrong

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

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

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 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!