Tuesday, June 21, 2016

Threads and their different state

Lets create different thread and put them into different states. And see what Jstack command output gives.
----------------------------------------------------------------------------------------------------------------
public class ThreadRunner {

public static void main(String[] args) {
//        NEW, RUNNABLE,
Thread runningJob = new Thread(new RunningJob(), "RunningJob");
runningJob.start();

//        BLOCKED,
Account account  = new Account();
Thread blockedJob1 = new Thread(new BlockedJob(account), "blockedJob1");
Thread blockedJob2 = new Thread(new BlockedJob(account), "blockedJob2");
blockedJob1.start();
blockedJob2.start();
//        WAITING,
PriorityQueue<Sheep> priorityQueue1 = new PriorityQueue<Sheep>();
Thread waitingJob = new Thread(new WaitingJob(priorityQueue1), "waitingJob");
waitingJob.start();
//        TIMED_WAITING,
PriorityQueue<Sheep> priorityQueue2 = new PriorityQueue<Sheep>();
Thread timedWaintingJob = new Thread(new TimedWaitingJob(priorityQueue2), "timedWaintingJob");
timedWaintingJob.start();

//  SLEEPING JOB
Thread sleepingJob = new Thread(new SleepingJob(), "sleepingJob");
sleepingJob.start();
    }
}

---------------------------------------------------------------------------------------------------------------
public class RunningJob implements Runnable {
public void run() {
while (true) {
System.out.println(Thread.currentThread().getName() + " Runing ");
}
}
}
-----------------------------------------------------------------------------------------------------------------
public class BlockedJob implements Runnable {

private Account account;
public BlockedJob(Account account) {
this.account = account;
}
public void run() {

System.out.println("BlockedJob is going to block " + Thread.currentThread().getName());
synchronized (account) {
while (true) {
System.out.println("BlockedJob inside synchronized block " + Thread.currentThread().getName());
}
}
}
}
-------------------------------------------------------------------------------------------------------------------
public class WaitingJob implements Runnable {

private Queue<Sheep> queue;
public WaitingJob(Queue<Sheep> queue) {
this.queue = queue;
}
public void run() {
synchronized (queue) {
if(queue.isEmpty()){
System.out.println("WaitingJob is going to wait");
try {
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
-----------------------------------------------------------------------------------------------------------------
public class TimedWaitingJob implements Runnable {

private Queue<Sheep> queue;
public TimedWaitingJob(Queue<Sheep> queue) {
this.queue = queue;
}
public void run() {
synchronized (queue) {
if (queue.isEmpty()) {
System.out.println("TimedWaitingJob is going to wait");
try {
queue.wait(5 * 1000 * 60 * 60);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}
}
------------------------------------------------------------------------------------------------------------------
public class SleepingJob implements Runnable {

public void run() {
while(true){
try {
Thread.sleep(100000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}
}
--------------------------------------------------------------------------------------------------------------------
arham@arham-Lenovo-G510:~$ jstack 3611
"sleepingJob" prio=10 tid=0x00007f90640b9000 nid=0xe33 waiting on condition [0x00007f9058578000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.thread.jobs.SleepingJob.run(SleepingJob.java:8)
at java.lang.Thread.run(Thread.java:745)

"timedWaintingJob" prio=10 tid=0x00007f90640b7000 nid=0xe32 in Object.wait() [0x00007f9058679000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000c6006898> (a java.util.PriorityQueue)
at com.thread.jobs.TimedWaitingJob.run(TimedWaitingJob.java:18)
- locked <0x00000000c6006898> (a java.util.PriorityQueue)
at java.lang.Thread.run(Thread.java:745)

"waitingJob" prio=10 tid=0x00007f90640b5000 nid=0xe31 in Object.wait() [0x00007f905877a000]
   java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000c600a068> (a java.util.PriorityQueue)
at java.lang.Object.wait(Object.java:503)
at com.thread.jobs.WaitingJob.run(WaitingJob.java:17)
- locked <0x00000000c600a068> (a java.util.PriorityQueue)
at java.lang.Thread.run(Thread.java:745)

"blockedJob2" prio=10 tid=0x00007f90640b2000 nid=0xe30 waiting for monitor entry [0x00007f905887b000]
   java.lang.Thread.State: BLOCKED (on object monitor)
at com.thread.jobs.BlockedJob.run(BlockedJob.java:16)
- waiting to lock <0x00000000c600c068> (a com.thread.dto.Account)
at java.lang.Thread.run(Thread.java:745)

"blockedJob1" prio=10 tid=0x00007f90640b0000 nid=0xe2f runnable [0x00007f905897c000]
   java.lang.Thread.State: RUNNABLE
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:345)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
- locked <0x00000000c600a228> (a java.io.BufferedOutputStream)
at java.io.PrintStream.write(PrintStream.java:482)
- locked <0x00000000c600a100> (a java.io.PrintStream)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
- locked <0x00000000c6006960> (a java.io.OutputStreamWriter)
at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
at java.io.PrintStream.write(PrintStream.java:527)
- eliminated <0x00000000c600a100> (a java.io.PrintStream)
at java.io.PrintStream.print(PrintStream.java:669)
at java.io.PrintStream.println(PrintStream.java:806)
- locked <0x00000000c600a100> (a java.io.PrintStream)
at com.thread.jobs.BlockedJob.run(BlockedJob.java:16)
- locked <0x00000000c600c068> (a com.thread.dto.Account)
at java.lang.Thread.run(Thread.java:745)

"RunningJob" prio=10 tid=0x00007f90640ae800 nid=0xe2e waiting for monitor entry [0x00007f9058a7d000]
   java.lang.Thread.State: BLOCKED (on object monitor)
at java.io.PrintStream.println(PrintStream.java:805)
- waiting to lock <0x00000000c600a100> (a java.io.PrintStream)
at com.thread.jobs.RunningJob.run(RunningJob.java:7)
at java.lang.Thread.run(Thread.java:745)

---------------------------------------------------------------------------------------------------------------
Output:- Every thing can be understand easily except RunningJob is in BLOCKED state cause it is blocked on object monitor which is PrintStream out. Println method is synchronized. So if any other thread is writing then all other thread will be blocked. 

Sunday, June 19, 2016

Few things about Custom Class Loading

Class loader in Java:

An java app that begins with main method has three class loader level. And remember all class loader are Java classes and all these should have a instance. And when we talk about class loader actually we will be talking about the instance of that class loader.
1. BootStrapClassLoader // That load classes from rt.jar
2. sun.misc.Launcher$ExtClassLoader // That load classes from  /usr/lib/jvm/java-7-oracle/jre/lib/ext:/usr/java/packages/lib/ext which you can come to know by using System.getProperty("java.ext.dirs") method.
3. sun.misc.Launcher$AppClassLoader // That load your main class

I have build the scenario. Lets try to understand using that.
I built one class below
package com;
public class CustomClass {

static{
System.out.println("Custom class that is inside /usr/lib/jvm/java-7-oracle/jre/lib/ext dir");
}
public static void check() {
System.out.println("java.ext.dirs = " + System.getProperty("java.ext.dirs"));
}
}

And putted that class inside one jar classloaderunrevieled.jar and putted that jar inside /usr/lib/jvm/java-7-oracle/jre/lib/ext.

And after that I build another class below

package com.tester;

import com.CustomClass;

public class ClassLoaderTester {

public static void main(String[] args) {

CustomClass.check();
System.out.println("ClassLoaderTester ran");
System.out.println("CustomClass.class.getClassLoader() : " + CustomClass.class.getClassLoader());
System.out.println("ClassLoaderTester.class.getClassLoader() :  " + ClassLoaderTester.class.getClassLoader());
}
}

Then before running the app I put the same classloaderunrevieled.jar in the  sun.misc.Launcher$AppClassLoader class path as that would be the one that will be running the main class.

Then I ran the ClassLoaderTester and the below output I got.
Output:-

Custom class that is inside /usr/lib/jvm/java-7-oracle/jre/lib/ext dir
java.ext.dirs = /usr/lib/jvm/java-7-oracle/jre/lib/ext:/usr/java/packages/lib/ext
ClassLoaderTester ran
CustomClass.class.getClassLoader() : sun.misc.Launcher$ExtClassLoader@60f32dde
ClassLoaderTester.class.getClassLoader() :  sun.misc.Launcher$AppClassLoader@2bb0bf9a

--------------------
So using output we can understand when our ClassLoaderTester ran it went to and loaded the class using AppClassLoader and then when it saw it also need CustomClass to load jvm went to AppClassLoader as it was the one that loaded the ClassLoaderTester class. So what AppClassLoader did, it tried to find the class if it has loaded it or not. It saw, no it have not loaded it, AppClassLoader asked it parent ExtClassLoader if it has loaded the class it saw, no it also have not loaded the class. So ExtClassLoader went ahead and asked BootStrapClassLoader if it have loaded the class. It also saw, no it did not load the class. BootStrapClassLoader does not have parent so it will try to load the class if it does not find the class it throw ClassNotFoundException and that will be caught by the ExtClassLoader and it will call its findClass method to find the class. As we know that we have putted the classloaderunrevieled.jar inside ext dir and that is having CustomClass in it. ExtClassLoader will be able to load the class and Jvm will register that class loader as the loader of that class. When next time call will be made to method findLoadedClass which is native method call, from ExtClassLoader, JVM will return the loaded. So ExtClassLoader return the loaded class to AppClassLoader. And then call to check method went ahead. As inside check method we checked who is the loader of the CustomClass it is printing ExtClassLoader.

-------
If we keep every thing same but just remove the classloaderunrevieled.jar from /usr/lib/jvm/java-7-oracle/jre/lib/ext dir the output will be changed to below output

Output:-

Custom class that is inside /usr/lib/jvm/java-7-oracle/jre/lib/ext dir
java.ext.dirs = /usr/lib/jvm/java-7-oracle/jre/lib/ext:/usr/java/packages/lib/ext
ClassLoaderTester ran
CustomClass.class.getClassLoader() : sun.misc.Launcher$AppClassLoader@55c4d594 // *********** Changed line
ClassLoaderTester.class.getClassLoader() :  sun.misc.Launcher$AppClassLoader@55c4d594


Now we can easyly understand why it got changed.

So how to write your own class loader?
As we have learned the correct way to load the class is to override the findClass method.
As it will be called when no other class loader will be able to laod the class based upon the above explaination.
Lets write our own class loader. But in this we will override loadClass method. It is for explaining some point that we will discuss leter.

package com.classloader;

public class CustomClassLoader extends ClassLoader {

public CustomClassLoader(ClassLoader parent) {
super(parent);
}

private Class<?> getClass(String name) throws ClassNotFoundException {
String file = name.replace('.', File.separatorChar) + ".class";
file = "bin"+File.separatorChar + file;
byte[] b = null;
try {
b = loadClassData(file);
Class<?> c = defineClass(name, b, 0, b.length);
resolveClass(c);
return c;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}

@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
System.out.println("loading class '" + name + "' ");
if (name.startsWith("com.classestolaod")) {
return getClass(name);
}
return super.loadClass(name);
}

private byte[] loadClassData(String name) throws IOException {
  name = System.getProperty("user.dir") + File.separatorChar + name;
InputStream stream =new FileInputStream(new File(name));
int size = stream.available();
byte buff[] = new byte[size];
DataInputStream in = new DataInputStream(stream);
in.readFully(buff);
in.close();
return buff;
}

@Override
protected void finalize() throws Throwable {
System.out.println("CustomClassLoader instance getting unloaded");
super.finalize();
}
}
--------------------------------------------------------------------------------------------------
Now lets modify the ClassLoaderTester

package com.tester;

public class ClassLoaderTester {

public static void main(String[] args) throws ClassNotFoundException, InstantiationException,
IllegalAccessException {

CustomClassLoader ccl = new CustomClassLoader(ClassLoaderTester.class.getClassLoader());
Class<?> loadedClass = ccl.loadClass("com.classestolaod.DummyClass");
}
}

-------------------------------------------------------------------------------------------------------
package com.classestolaod;

public class DummyClass {

static {
System.out.println("class loaded "+  DummyClass.class.getClassLoader());
}

public DummyClass(){
System.out.println("DummyClass constructor");
}
}

---------------------------------------------------------------------------------------------------------
Output:-
loading class 'com.classestolaod.DummyClass'
loading class 'java.lang.Object'



-----------------------------------------------------------------------------------------------------------
Lets discuss the flow.
First it will call the loadClass method of CustomClassLoader and it will check if it belong to package com.classestolaod and if it is then it will try to load it. If now then it will call the super class loadClass method. Now CustomClassLoader's getClass method first will call loadClassData(file) method, that will just convert the .class file to byte array. Then it will call the Class<?> c = defineClass(name, b, 0, b.length) method that have very high significance in class loading. Because whatever ClassLoader's implementation call this method, after class loading is done, then jvm call the below ClassLoader's addClass method to record all the loaded class by this class loader. So when next time request will come and findLoadedClass(name); method is invoked, which is native method, jvm will return the loaded class by the current class loader instance if it is already loaded. As we can see while it was loading the DummyClass it also loaded the Object class. Because Object class is extended by DummyClass. And as we know for loading the Object class it will use the DummyClass's class loader to load the Object class hence the jvm made the loadClass method call of CustomClassLoader. As our code is loading the classes from package com.classestolaod it will delegate this to parent ClassLoader.


    // Invoked by the VM to record every loaded class with this loader.
    void addClass(Class c) {
        classes.addElement(c);
    }

    // Invoked by the VM to record every loaded class with this loader.
    void addClass(Class c) {
        classes.addElement(c);
    }

So now if change the code like below

public class ClassLoaderTester {

public static void main(String[] args){

CustomClassLoader ccl = new CustomClassLoader(ClassLoaderTester.class.getClassLoader()); //1
Class<?> loadedClass = ccl.loadClass("com.classestolaod.DummyClass");//2
Object newInstance = loadedClass.newInstance();//3
System.out.println("Main finished");//4

DummyClass dummyClass = new DummyClass();//5
CustomClassLoader ccl2 = new CustomClassLoader(ClassLoaderTester.class.getClassLoader());//6
Class<?> loadedClass2 = ccl2.loadClass("com.classestolaod.DummyClass");//7

}
}
---------------------------------------------------------------------------------------------------------
Output"-
loading class 'com.classestolaod.DummyClass'
loading class 'java.lang.Object'
loading class 'java.lang.System'
loading class 'java.lang.StringBuilder'
loading class 'java.lang.Class'
loading class 'java.io.PrintStream'
class loaded com.classloader.CustomClassLoader@439a8942
DummyClass constructor
Main finished
class loaded sun.misc.Launcher$AppClassLoader@6da21389
DummyClass constructor
loading class 'com.classestolaod.DummyClass'
loading class 'java.lang.Object'


--------------------------------------------------------------------------------------------------------------

Till line 2 we are clear. So in line 3 when we create the instance of DummyClass it needed other class to load as we have seen erlier it will use the class loader of current class. JVM used the CustomClassLoader to load the System, StringBuilder, Class and PrintStream classes. Actully what JVM do is when it refers a new class it checks the class loader context also. Means when it is loading the class for DummyClass, CustomClassLoader was the class loader for this. So when Object class was needed jvm checked using method findLoadedClass(name) if it currently loaded using the CustomClassLoader or not. It was not. As we know that it must have been already loaded by the BootstrapClassLoader. So jvm called the loadClass method of CustomClassLoader to load the Object class but it delegated it to parent class loader.

When on line 5 executed, jvm checked using  findLoadedClass using current class loader in this case it will be AppClassLoader, if DummyClass is already loaded or not. But it was not loaded so it loaded it. As you can see it did not load the Object class here as it was already loaded.
In line 6 and 7 we created the new CustomClassLoader instance and loaded the DummyClass again it did the same thing as earlier as it was new instance of class loader.

--------------------------------------------------------------------------------------------------------------------
What if change the code like below
CustomClassLoader ccl = new CustomClassLoader(ClassLoaderTester.class.getClassLoader()); // 1

Class<?> loadedClass = ccl.loadClass("com.classestolaod.DummyClass"); //2
Class<?> loadedClass2 = ccl.loadClass("com.classestolaod.DummyClass"); //3


----------------------------------------------------------------------------------------------------------------------
Output:-

loading class 'com.classestolaod.DummyClass'
loading class 'java.lang.Object'
loading class 'com.classestolaod.DummyClass'
Exception in thread "main" java.lang.LinkageError: loader (instance of  com/classloader/CustomClassLoader): attempted  duplicate class definition for name: "com/classestolaod/DummyClass"
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.lang.ClassLoader.defineClass(ClassLoader.java:643)
at com.classloader.CustomClassLoader.getClass(CustomClassLoader.java:22)
at com.classloader.CustomClassLoader.loadClass(CustomClassLoader.java:35)
at com.tester.ClassLoaderTester.main(ClassLoaderTester.java:22)
-----------------------------------------------------------------------------------------------------------------
When we tried to load the same class again using the same class loader we got the LinkageError when it called the defineClass method.
As we have mentioned earlier defineClass method has significance. Means jvm record this class loader as loader of the class. So when you tried to load it again using the same class loader it thrown duplicate class loading attempt.

Saturday, May 14, 2016

Useful command to know more about Java thread

Few days back a new bug came so I did what a good programmer would do. I fixed it.
I did my part of the testing in my development environment. And moved the code to testing environment. The code fix was regarding a schedule task, that used to take file from some location and used to process it line by line. So I started the scheduled task and started to see the logs of test environment. Task was successfully launched that I could see in the logs. But after that nothing was happening means nothing was coming in the logs. So checked the file that was supposed to be processed by the task. It was locked by the task as we were using Camel, so it appended the .lock in the end of the file. The point is file was picked up by the task, but nothing was happening after that. So I thought it is stuck there cause of my changed code. But I was not able to figure out why?

So after that I came to know about the command "kill -3 pid", that was shown by one of my colleague. What it did is dumped the information about all the threads stack trace those were belonging to that process. So I could see that my thread was executing some method. As file was very big, having around half a million record in it.

So after that I started to look what we can do if we get into this kind of situations. What are the tools we have to tackle such problems.

Note:- Threads are a popular programming abstraction for parallel execution on modern operating systems. When threads are forked inside a program for multiple flows of execution, these threads share certain resources (e.g., memory address space, open files) among themselves to minimize forking overhead and avoid expensive IPC (inter-process communication) channel. These properties make threads an efficient mechanism for concurrent execution.
In Linux, threads (also called Lightweight Processes (LWP)) created within a program will have the same "thread group ID" as the program's PID. Each thread will then have its own thread ID (TID). To the Linux kernel's scheduler, threads are nothing more than standard processes which happen to share certain resources. Classic command-line tools such as ps or top, which display process-level information by default, can be instructed to display thread-level information.
Here are a few things you need to know before starting. Following the links is not necessary, they are available for the reference.
  • there are different vendors of Java Virtual Machine. This post is about Oracle’s JVM which is called HotSpot. Linux x86-64 is considered as OS platform. Most of the things about HotSpot are applicable to other vendors too but with slight changes. OSes other than Linux may add some more complications
  • it’s called Virtual Machine, because it virtualizes runtime environment for a Java application. So to know where to look at you need to know a few things about how specific VM is organized. For a detailed overview of the HotSpot, please refer to this article
  • on Linux, a thread inside HotSpot VM is mapped directly to an OS level thread. Well, it may not be true on all OSes, but for modern Linux kernels this is true. So every thread on the OS level is a thread inside a Java application
  • there are generally two types of threads inside a HotSpot VM: native and application threads. Application threads are those that run some Java code, and usually this is what applications are using to run their code. Native threads run something which is not written in Java, usually it’s code in C/C++ and usually all these threads are special utility threads started by a VM itself.
That note is just to make you clear about the thread.
jps(JVM Process Status):-
                                           The jps tool lists the instrumented HotSpot Java Virtual Machines (JVMs) on the target system. The tool is limited to reporting information on JVMs for which it has the access permissions.
The jps command will report the local VM identifier, or lvmid, for each instrumented JVM found on the target system. The lvmid is typically, but not necessarily, the operating system's process identifier for the JVM process. With no options, jps will list each Java application's lvmid followed by the short form of the application's class name or jar file name. The jps command uses the java launcher to find the class name and arguments passed to the main method.

-m: Output the arguments passed to the main method. The output may be null for embedded JVMs.
-l: Output the full package name for the application's main class or the full path name to the application's JAR file.
-v: Output the arguments passed to the JVM.
-V: Output the arguments passed to the JVM through the flags file (the .hotspotrc file or the file specified by the -XX:Flags=<filename> argument).


OUTPUT FORMAT
The output of the jps command follows the following pattern:

lvmid [ [ classname | JARfilename | "Unknown"] [ arg* ] [ jvmarg* ] ]

Example : -
jps
4071 com.analyzer.thread.JobRunner
18032 jps
18005 jstat

So using above tool you will come to know lvmid (that is in most cases is the os pid) of all the VM that is running on that machine.

Now lets dig more using lvmid that we got from the above command.

Now using that lvmid or for discussion pid we can come to know stack trace of all the threads of given process. We can come to know what is our thread is doing. It is in which state?  Is it running or sleeping?

jstack:-
jstack prints Java stack traces of Java threads for a given Java process. For each Java frame, the full class name, method name, 'bci' (byte code index) and line number, if available, are printed.

Example:-
jstack 4071


Output:-2016-05-15 00:42:02

"t2" prio=10 tid=0x00007f67200ab800 nid=0x2d6e waiting on condition [0x00007f6713af9000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
 at java.lang.Thread.sleep(Native Method)
 at com.analyzer.thread.Job.run(Job.java:8)
 at java.lang.Thread.run(Thread.java:745)

"t1" prio=10 tid=0x00007f67200aa000 nid=0x2d6d waiting on condition [0x00007f6713bfa000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
 at java.lang.Thread.sleep(Native Method)
 at com.analyzer.thread.Job.run(Job.java:8)
 at java.lang.Thread.run(Thread.java:745)




top:-
Using jps command we will come to know about the pid of our java app. Now we can use the top command to know pid of our threads.

top -H -p 4071

Output:
  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                     
 4091 arham     20   0 2258864  59000  10304 S  6.0  1.6   3:49.35 java                                                                        

 4090 arham     20   0 2258864  59000  10304 S  5.3  1.6   3:45.30 java 


So what we see as nid=0x2d6d in jstack output is PID=4091 in top output are the same.
Where nid stands for native id.

So now if we want to see if something is being done our thread 4091 in we will have to keep looking the stack trace using jstack. For this we can use 'watch' command.

Command :-
jstack 4071 | awk '/ nid='"$(printf '%#x' 4091)"' /,/^$/'    //Just to print your stack frame.

watch -n .5 jstack 4071 | awk '/ nid='"$(printf '%#x' 4091)"' /,/^$/'  //For keep watch your stack frame

Reference:-https://www.pythian.com/blog/a-simple-way-to-monitor-java-in-linux/

















Monday, January 18, 2016

Volatile real use

So there are two thing we can do with volatile in Java.

1. Declaring primitive volatile
2. Declaring object volatile

So lets see what happens with each when we declare it volatile.

1. Declaring primitive as volatile:-




Lets try to understand above diagram.
So in this we have declared two variable a and b as normal int but c as volatile int.
Then thread T1 writing to a then b and at the same time or some time difference thread t2 is reading a and b.
So T2 may read  0 or 7 for a and 0 or 8 for b. Because when T1 write to a and b it will first write that in its cache. But it is also possible, that value of a and b may also get pushed to main memory. But it is not guaranteed.

But when T1 reaches line c=9, and execute it, now it is guaranteed that other thread like T2 will see the changes now, that are done by T1. But it is conditional on that, they read value of volatile c first that is modified by T1.

So what are the rule that we can take out from above explanation.
1. When volatile write happens, every thing before this should be completed.
2. When read happens, reader thread will see who has changed(means different from earlier read) the value of volatile and that thread can see all the changes that are done by writer thread.

2. Declaring object volatile:-
 
Declaring object as volatile has the same impact as primitive.
1.  Means when writing to reference variable means assigning a object to it, all the instruction(As the object creation is divided into three parts) before it should be completed. And its value means the address to which this reference variable is pointing now, will be pushed to main memory .
2. And when reading a reference variable, read from main memory, means see if the reference variable is still pointing to the same object or not. If it is still pointing to the same object then reader thread may not notice any difference. Because according to rule 2 reader thread will see no difference in reference variable, as it is still pointing to same object(think of some numeric object address) so if any changes are done to non volatile member variable of that volatile reference variable it may not notice any difference.



So know we will have to understand what is stored in a reference variable. A reference variable just store the address of object.

Lets try to understand above diagram. In this thread T1 assign creates a new object and assign it to animal reference variable. So what gets store in animal reference variable is address 2000. And same value for reference variable.  Then in T2 thread it creates new object which has address 2002 and assign it same animal reference variable. So now think, when thread T1 want to change the value of animal name what it will do. It will first read the animal reference variable value and it will see that it having 2000 stored in its cache. So it will go to address 2000 and modify that object in the heap. It got the animal reference variable value 2000 from its cache only. As we were doing with primitive. But if it were went to main memory also, there is no guarantee it will 2002 as value of animal reference variable because it may also happen that T2 may have written it in its cache only. So main memory will still have 2000 as the value of animal reference variable.

Solution to above problem is declare the animal reference variable volatile. So any thread will read or write to animal reference variable it will always go to main memory.So both will see value of animal refernce variable as 2002.

Lets elaborate point 1 little bit.
Declaring an object volatile has some advantage when we are creating an object and do not want partially initialized object to be used by other thread.

Actually creation of an object is 3 step statement. So when execute below statement 3 things happens

class Animal{
private String name = "Some Name";
}

volatile Animal animal = new Animal();

So when above statement is executed three things happens. They should be executed in the same order but for performance reason processor may choose to execute it in different order.

a. Memory Allocation
b. Memory Initialization
c. Reference assignment

So if we don't declare animal object as volatile it can follow below execution.
a -> c ->b

So think a->c has been executed in thread T1 but not b, and other thread T2 now may see animal has been assigned. So it can see partially initialized object.
So for stopping such kind of behavior we should declare it volatile. So in that case when c instruction comes for execution, processor will see that it should complete a and b instruction before executing c. So it will complete instruction a and b.  Then when c instruction is executed which assigning to a volatile variable.
When some other thread comes and read that volatile refenece variable it will see it have been changed, so it will see all the changes till now whatever is done by thread T1

These above guarantee is provided by JMM. So JMM is responsible for providing these semantics. They may be using some processor level instruction to implement these semantics.

So the only use of volatile is to provide these semantics only. That is it.

So to conclude declaring refence varialbe as volatile gives us.
1. Uninitialiezed object will not skip.
2. Reference variable will always point to correct object.



But we some time misunderstand it, and gets confuse and think that if we declare an object volatile so its all member variables will have updted value.

Declaring an object as volatile does not have to do anything with its member variable.It does not provide any kind of protection for those varialble.