1

My understanding is that Java allows threads to access shared variables. As a rule, to ensure that shared variables are consistently updated, a thread should ensure that it has exclusive use of such variables by obtaining a lock that enforces mutual exclusion for those shared variables.If a field is declared volatile, in that case the Java memory model ensures that all threads see a consistent value for the variable.

In case of program below , tickectsAvailable is a shared variable which is stored on heap and because thread1 and thread2, are created on same object "obj" , both thread1 and thread2 have access to obj

I am trying to understanding when to make a variable volatile. Correct use case would be here in this case making "tickectsAvailable" volatile. Is my understanding on volatile variables correct?

I read an article that says : Each thread may copy variables from main memory into a CPU cache while working on them, for performance reasons. If your computer contains more than one CPU, each thread may run on a different CPU. That means, that each thread may copy the variables into the CPU cache of different CPUs

In this case, if i do not make "tickectsAvailable" volatile, there are changes that threads may read from CPU cache if i have multiple threads working of same object("obj") here in case of only more than one CPU?

Should Volatile variable be used only when your computer contains multiple CPU's? But if i have multiple threads on same obj and one cpu how is it going to behave?

class TicketBooking implements Runnable{
        int ticketsAvailable=1;

        public void run(){

               System.out.println("Waiting to book ticket for : "+Thread.currentThread().getName());
               synchronized (this) {
                      if(ticketsAvailable>0){
                            System.out.println("Booking ticket for : "+Thread.currentThread().getName());

                            //Let's say system takes some time in booking ticket (here we have taken 1 second time)
                            try{
                                   Thread.sleep(1000); 
                            }catch(Exception e){}

                            ticketsAvailable--;
                            System.out.println("Ticket BOOKED for : "+ Thread.currentThread().getName());
                            System.out.println("currently ticketsAvailable = "+ticketsAvailable);
                      }
                      else{
                            System.out.println("Ticket NOT BOOKED for : "+ 
                                      Thread.currentThread().getName());
                      }

               }//End synchronization block


        }

    }

    /** Copyright (c), AnkitMittal JavaMadeSoEasy.com */
    public class MyClass {
        public static void main(String args[])
        {
               TicketBooking obj=new TicketBooking();

               Thread thread1=new Thread(obj,"Passenger1 Thread");
               Thread thread2=new Thread(obj,"Passenger2 Thread");

               thread1.start();
               thread2.start();

        }

    }

    /*OUTPUT

    Waiting to book ticket for : Passenger2 Thread
    Waiting to book ticket for : Passenger1 Thread
    Booking ticket for : Passenger2 Thread
    Ticket BOOKED for : Passenger2 Thread
    currently ticketsAvailable = 0
    Ticket NOT BOOKED for : Passenger1 Thread

    */
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
tech_questions
  • 263
  • 5
  • 14

2 Answers2

0

Volatile variable guarantees happen before relation. If only one thread is writing and all other threads are reading a variable, in that case volatile variables ensure thread safety. In other scenarios you have to use other synchronization mechanisms as per your need.

Should Volatile variable be used only when your computer contains multiple CPU's? But if i have multiple threads on same obj and one cpu how is it going to behave?

Operating system scheduler allocate CPU for every thread. Every core can process one or more threads depends on hardware capability. Volatile variables is an abstraction within language, and it does not have any direct correlation with hardware capabilities.

Community
  • 1
  • 1
Steephen
  • 14,645
  • 7
  • 40
  • 47
0

Should Volatile variable be used only when your computer contains multiple CPU's?

Unless you are writing code for an embedded system, then optimizing your code for a specific hardware platform probably is a waste of your time. It could even be a costly mistake in the long run.

If you are writing Java code, then it's pretty likely that you are writing a service, or a web app, or a mobile app, or a desktop app. If you are writing any of those things, then your target should be the the generic Java platform or maybe, the Java platform and some particular SDK or framework. Do yourself a favor and don't worry about the make and model of any computer or cell phone.

If a field is declared volatile, ... Java ... ensures that all threads see a consistent value for the variable

Any time you use the word, "consistent," you should ask yourself, "consistent with what?"

If you mark a single variable as volatile, then all threads will see the value of the variable to be consistent with itself. That is, if you have a double d=0.0;, and thread A sets d=1.0;, and thread B calls system.out.println(d); at approximately the same time, then thread B is guaranteed to print either 0.0 or 1.0. It will never print any other value.

Perhaps more significantly, if a volatile variable is updated many times, then all threads will agree upon one consistent order in which the updates happened.

But, if you want several variables to be consistent with each other, then you should be protecting that group of variables with synchronized blocks or with a java.util.concurrent.locks.ReentrantLock object, and forget about volatile.

Each thread may copy variables from main memory into a CPU cache...

There is no "cache" in Java. Java has its memory model. CPU caches are the hidden reason behind the memory model. If you are implementing a JVM for some particular computer platform, then, hopefully, the Java memory model gives you some freedom to exploit the platform's cache system to your advantage.

If you are writing code for the Java platform, then you should worry first about the Java memory model, and whether or not your program will behave correctly in the face of it. Learning about cache memory systems is an extra-curricular activity that may help you to feel better about your understanding of why Java is the way it is.

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57