I wanted to examine the usage of private static volatile variable in multi-thread environment, and that is the example code which I had written:
package com.jeeprojectsnippets.volatilable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class JeeProjectSnippetsTest {
private static volatile int jeep = 1;
public static void main(String[] args) throws IOException,
ClassNotFoundException {
JeeProjectSnippets singleton = null;
for (int i = 1; i < 4; i++) {
UpdateReceiver updateReceiver = new UpdateReceiver();
updateReceiver.start();
singleton = JeeProjectSnippets.getInstance();
UpdateTransmitter updateTransmitter = new UpdateTransmitter();
updateTransmitter.start();
File file = new File("ser" + i + ".txt");
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(file));
JeeProjectSnippets.a++;
singleton.b++;
JeeProjectSnippets.c++;
singleton.d++;
JeeProjectSnippets.f++;
oos.writeObject(singleton);
oos.close();
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream(file));
JeeProjectSnippets jps = (JeeProjectSnippets) ois.readObject();
System.out.println("main() in JeeProjectSnippetsTest: " +i + ". Variable jeep equals: " + jeep);
System.out.println("main() in JeeProjectSnippetsTest: " +i + ". a_static: " + JeeProjectSnippets.a);
System.out.println("main() in JeeProjectSnippetsTest: " +i + ". b_transient: " + jps.b);
System.out.println("main() in JeeProjectSnippetsTest: " +i + ". c_static_volatile: " + JeeProjectSnippets.c);
System.out.println("main() in JeeProjectSnippetsTest: " +i + ". d_volatile: " + jps.d);
System.out.println("main() in JeeProjectSnippetsTest: " +i + ". f_static_transient: " + JeeProjectSnippets.f + "\n");
ois.close();
}
}
/**
* JeeProjectSnippets class is a simple Singleton implementation. This
* example demonstrates when is useful to use volatile keyword in Java. I
* use volatile variable in this example to ensure that every thread can see
* already updated value of instance.
*/
public static class JeeProjectSnippets implements Serializable {
private static final long serialVersionUID = 5808143804530443067L;
private static int a = 1;
private transient int b = 1;
private static volatile int c = 1;
private volatile int d = 1;
private static transient int f = 1;
private static volatile JeeProjectSnippets instance;
public static JeeProjectSnippets getInstance() {
if (instance == null) {
synchronized (JeeProjectSnippets.class) {
if (instance == null)
instance = new JeeProjectSnippets();
}
}
return instance;
}
}
public static class UpdateReceiver extends Thread {
@Override
public void run() {
JeeProjectSnippets singleton = JeeProjectSnippets.getInstance();
JeeProjectSnippets.a++;
singleton.b++;
JeeProjectSnippets.c++;
singleton.d++;
JeeProjectSnippets.f++;
int jeeLocal = jeep;
while ( jeeLocal < 4){
if( jeeLocal!= jeep){
System.out.println("run() in UpdateReceiver: " +jeeLocal + ". Variable jeep is updated: " + jeep);
System.out.println("run() in UpdateReceiver: " +jeeLocal + ". a_static: " + JeeProjectSnippets.a);
System.out.println("run() in UpdateReceiver: " +jeeLocal + ". b_transient: " + singleton.b);
System.out.println("run() in UpdateReceiver: " +jeeLocal + ". c_static_volatile: " + JeeProjectSnippets.c);
System.out.println("run() in UpdateReceiver: " +jeeLocal + ". d_volatile: " + singleton.d);
System.out.println("run() in UpdateReceiver: " +jeeLocal + ". f_static_transient: " + JeeProjectSnippets.f + "\n");
jeeLocal= jeep;
}
}
}
}
public static class UpdateTransmitter extends Thread{
@Override
public void run() {
JeeProjectSnippets singleton = JeeProjectSnippets.getInstance();
JeeProjectSnippets.a++;
singleton.b++;
JeeProjectSnippets.c++;
singleton.d++;
JeeProjectSnippets.f++;
int jeeLocal = jeep;
while (jeep < 4){
int temp = jeeLocal+1;
System.out.println("run() in UpdateTransmitter: " +jeep + ". Increment variable jeep to: " + temp);
System.out.println("run() in UpdateTransmitter: " +jeep + ". a_static: " + JeeProjectSnippets.a);
System.out.println("run() in UpdateTransmitter: " +jeep + ". b_transient: " + singleton.b);
System.out.println("run() in UpdateTransmitter: " +jeep + ". c_static_volatile: " + JeeProjectSnippets.c);
System.out.println("run() in UpdateTransmitter: " +jeep + ". d_volatile: " + singleton.d);
System.out.println("run() in UpdateTransmitter: " +jeep + ". f_static_transient: " + JeeProjectSnippets.f + "\n");
jeep = ++jeeLocal;
try {
Thread.sleep(400);
} catch (InterruptedException e) { e.printStackTrace(); }
}
}
}
}
And the output was as following:
run() in UpdateTransmitter: 1. Increment variable jeep to: 2
run() in UpdateTransmitter: 1. a_static: 4
run() in UpdateTransmitter: 1. b_transient: 4
run() in UpdateTransmitter: 1. c_static_volatile: 4
run() in UpdateTransmitter: 1. d_volatile: 4
run() in UpdateTransmitter: 1. f_static_transient: 4
run() in UpdateReceiver: 1. Variable jeep is updated: 2
run() in UpdateReceiver: 1. a_static: 4
run() in UpdateReceiver: 1. b_transient: 4
run() in UpdateReceiver: 1. c_static_volatile: 4
run() in UpdateReceiver: 1. d_volatile: 4
run() in UpdateReceiver: 1. f_static_transient: 4
main() in JeeProjectSnippetsTest: 1. Variable jeep equals: 2
main() in JeeProjectSnippetsTest: 1. a_static: 4
main() in JeeProjectSnippetsTest: 1. b_transient: 0
main() in JeeProjectSnippetsTest: 1. c_static_volatile: 4
main() in JeeProjectSnippetsTest: 1. d_volatile: 4
main() in JeeProjectSnippetsTest: 1. f_static_transient: 4
main() in JeeProjectSnippetsTest: 2. Variable jeep equals: 2
main() in JeeProjectSnippetsTest: 2. a_static: 6
main() in JeeProjectSnippetsTest: 2. b_transient: 0
main() in JeeProjectSnippetsTest: 2. c_static_volatile: 6
main() in JeeProjectSnippetsTest: 2. d_volatile: 6
main() in JeeProjectSnippetsTest: 2. f_static_transient: 6
main() in JeeProjectSnippetsTest: 3. Variable jeep equals: 2
main() in JeeProjectSnippetsTest: 3. a_static: 7
main() in JeeProjectSnippetsTest: 3. b_transient: 0
main() in JeeProjectSnippetsTest: 3. c_static_volatile: 7
main() in JeeProjectSnippetsTest: 3. d_volatile: 7
main() in JeeProjectSnippetsTest: 3. f_static_transient: 7
run() in UpdateTransmitter: 2. Increment variable jeep to: 3
run() in UpdateTransmitter: 2. a_static: 8
run() in UpdateTransmitter: 2. b_transient: 8
run() in UpdateTransmitter: 2. c_static_volatile: 8
run() in UpdateTransmitter: 2. d_volatile: 8
run() in UpdateTransmitter: 2. f_static_transient: 8
run() in UpdateReceiver: 2. Variable jeep is updated: 3
run() in UpdateReceiver: 2. Variable jeep is updated: 3
run() in UpdateReceiver: 2. a_static: 8
run() in UpdateReceiver: 2. a_static: 8
run() in UpdateReceiver: 2. b_transient: 9
run() in UpdateReceiver: 2. c_static_volatile: 9
run() in UpdateReceiver: 2. d_volatile: 9
run() in UpdateReceiver: 2. f_static_transient: 9
run() in UpdateTransmitter: 3. Increment variable jeep to: 4
run() in UpdateTransmitter: 3. a_static: 10
run() in UpdateTransmitter: 3. b_transient: 10
run() in UpdateTransmitter: 3. c_static_volatile: 10
run() in UpdateTransmitter: 3. d_volatile: 10
run() in UpdateTransmitter: 3. f_static_transient: 10
run() in UpdateReceiver: 3. Variable jeep is updated: 4
run() in UpdateReceiver: 3. a_static: 10
run() in UpdateReceiver: 3. b_transient: 10
run() in UpdateReceiver: 3. c_static_volatile: 10
run() in UpdateReceiver: 3. d_volatile: 10
run() in UpdateReceiver: 3. f_static_transient: 10
run() in UpdateReceiver: 2. b_transient: 8
run() in UpdateReceiver: 2. c_static_volatile: 10
run() in UpdateReceiver: 2. d_volatile: 10
run() in UpdateReceiver: 3. Variable jeep is updated: 4
run() in UpdateReceiver: 2. f_static_transient: 10
run() in UpdateReceiver: 3. a_static: 10
run() in UpdateReceiver: 3. b_transient: 10
run() in UpdateReceiver: 3. c_static_volatile: 10
run() in UpdateReceiver: 3. d_volatile: 10
run() in UpdateReceiver: 3. f_static_transient: 10