Combination of Singleton class and volatile variable - java

As far as I know, volatile variables will be always read and written from the main memory. Then I think about the Singleton class. Here is how my program is:
1. Singleton class
public class Singleton {
private static Singleton sin;
private static volatile int count;
static{
sin = new Singleton();
count = 0;
}
private Singleton(){
}
public static Singleton getInstance(){
return sin;
}
public String test(){
count++;
return ("Counted increased!" + count);
}
}
2. Main class
public class Java {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Derived d1 = new Derived("d1");
d1.start();
Derived d2 = new Derived("d2");
d2.start();
Derived d3 = new Derived("d3");
d3.start();
}
;
}
class Derived extends Thread {
String name;
public Derived(String name){
this.name = name;
}
public void run() {
Singleton a = Singleton.getInstance();
for (int i = 0; i < 10; i++) {
System.out.println("Current thread: "+ name + a.test());
}
}
}
I know this maybe a dumb question, but i'm not good at multithreading in Java thus this problem confuses me a lot. I thought the static volatile int count variable in Singleton class will always have the latest value, but apparently it does not...
Can someone help me to understand this?
Thank you very much.

The problem is that volatile has nothing to do with thread synchronization. Even though the read from static volatile int count would indeed always return the latest value, multiple threads may write the same new value back into it.
Consider this scenario with two threads:
count is initialized zero
Thread A reads count, sees zero
Thread B reads count, sees zero
Thread A advances count to 1, stores 1
Thread B advances count to 1, stores 1
Thread A writes "Counted increased! 1"
Thread B writes "Counted increased! 1"
Both threads read the latest value, but since ++ is not an atomic operation, once the read is complete, each thread is on its own. Both threads independently compute the next value, and then store it back into the count variable. The net effect is that a variable is incremented once, even though both threads performed the increment.
If you would like to increment an int from multiple threads, use AtomicInteger.

As Jon Skeet indicated, it would be best if you use AtomicInteger. Using volatile variables reduces the risk of memory consistency errors, but it doesn't eliminate the need to synchronize atomic action.
I think this modification would help with your problem.
public synchronized String test(){
count++;
return ("Counted increased!" + count);
}

Reader threads are not doing any locking and until writer thread comes out of synchronized block, memory will not be synchronized and value of 'sin' will not be updated in main memory. both threads reads the same values and thus updates it by adding one, if you want to resolve make test method synchronised.
Read more: http://javarevisited.blogspot.com/2011/06/volatile-keyword-java-example-tutorial.html#ixzz3PGYRMtgE

Related

How to update a value of a variable in Thread class on some condition in the caller

Let us say I have two classes, A main class and a Thread class as follows:
public class A {
public static void main(String []args){
int count = 0;
for(int i = 0; i < 10; i++){
count+=10;
//here on every addition, I want to update the variable countOfAdd of the thread class
//and when countOfAdd value is in multiples of 5 I want to print a statement
}
}
class B extends Thread {
int countOfAdd;
#Override
public void run(){
//on value received
count+=1;
}
}
I don't know whether this is possible or not. If it is possible how to do it
Thanks in advance.
The normal way to do that is a queue.
Create a queue and make references to it available to both threads.
The main thread should add() an element to the queue (e.g. the amount of increment).
The other thread should poll() the queue and use this information to update its internal state.
This way none of the intermediate updates are going to be lost between the threads.
The quick and dirty way is direct access and locking.
Both of your threads can keep a reference to a common piece of data, and a common lock object (which can just be a Object commonLock = new Object()).
Every time either thread needs to access the data member, they do it holing a lock, e.g.:
synchronized (commonLock) { commonCount +=1; } // One thread.
synchronized (commonLock) { if (commonCount > 1) {...} } // Another thread.
This is harder to reason about, but can be made serviceable if the number of accesses in each thread is made small, preferably just one.
I don't know why you are using Thread here but anyway.
1. Without Thread
public class A {
public static void main(String []args){
int count = 0;
B objectB = new B();
for(int i = 0; i < 10; i++){
count+=10;
//here on every addition, I want to update the variable countOfAdd
//of the thread class and when countOfAdd value is in multiples of 5
//I want to print a statement
objectB.setCount(YourInput);// set your value
if(objectB.getValue()%5==0){
//do your task
}
}
}
class B {
int countOfAdd;
public int getCount(){return countOfAdd;}
public void setCount(int ){this.countOfAdd =countOfAdd;}
}
2. With Thread
Use Pub-sub pattern
Implementation of pub sub pattern in Java

Why a synchronized getter work like a volatile read?

This program does not terminate!
public class Main extends Thread {
private int i = 0;
private int getI() {return i; }
private void setI(int j) {i = j; }
public static void main(String[] args) throws InterruptedException {
Main main = new Main();
main.start();
Thread.sleep(1000);
main.setI(10);
}
public void run() {
System.out.println("Awaiting...");
while (getI() == 0) ;
System.out.println("Done!");
}
}
I understand this happens because the CPU core running the Awaiting loop always sees the cached copy of i and misses the update.
I also understand that if I make volatileprivate int i = 0; then the while (getI()... will behave[1] as if every time it is consulting the main memory - so it will see the updated value and my program will terminate.
My question is: If I make
synchronized private int getI() {return i; }
It surprisingly works!! The program terminates.
I understand that synchronized is used in preventing two different threads from simultaneously entering a method - but here is only one thread that ever enters getI(). So what sorcery is this?
Edit 1
This (synchronization) guarantees that changes to the state of the object are visible to all threads
So rather than directly having the private state field i, I made following changes:
In place of private int i = 0; I did private Data data = new Data();, i = j changed to data.i = j and return i changed to return data.i
Now the getI and setI methods are not doing anything to the state of the object in which they are defined (and may be synchronized). Even now using the synchronized keyword is causing the program to terminate! The fun is in knowing that the object whose state is actually changing (Data) has no synchronization or anything built into it. Then why?
[1] It will probably just behave as that, what actually, really happens is unclear to me
It is just coincidence or platform dependent or specific JVM dependent, it is not guaranteed by JLS. So, do not depend on it.

Thread stuck in infinite loop despite updated value

I was given a question by my friend and was asked to explain why the program could get hung in infinite loop.
public class Test {
private static boolean flag;
private static int count;
private static class ReaderThread extends Thread {
public void run() {
while (!flag)
Thread.yield();
System.out.println(count);
}
}
public static void main(String[] args) {
new ReaderThread().start();
count = 1;
flag = true;
}
}
I was sure that it cannot happen. But it did actually happen one time (out of probably 50 times).
I am not able to explain this behavior. Is there any catch that I am missing?
From book - Java Concurrency In Practice (this example seems to be taken from the book itself).
When the reads and writes occur in different threads, there is no guarantee that the reading thread will see a value written by another thread on a timely basis, or even at all because threads might cache these values.
In order to ensure visibility of memory writes across threads, you must use synchronization or declare variable as volatile.

Multi threading

I have an idea about multi-threading but I never worked on it. So, when I see my application at work... I haven't seen any class extending Thread creating a Thread. So, synchronized keyword is used when 2 objects try to access a variable at the same time.. we use synchronized to avoid conflicts.
Example:
public class Test {
private static int count = 0;
public static synchronized void incrementCount() {
count++;
}
}
If test class was using by an object then it makes sense to add synchronized to incrementcount(). But when you don't extend Thread or Runnable then what's the use of writing synchronized.
Synchronized isn't for threads or Runnables, it's used for data structures that are accessed by multiple threads in order to make sure each thread accesses them in a way that doesn't corrupt their data. Your own example is a rudimentary case of this, where count is incremented in a way that isn't threadsafe (using ++, see this question), so it needs locking to make sure only one thread at a time can increment it.
If there's other code that accesses count it also needs to be synchronized so that updates to count are visible to it. If all you're doing is incrementing a counter then it makes more sense to use a class like java.util.concurrent.atomic.AtomicInteger, and you can do without the synchronized keyword altogether.
For using synchronized to make sense it does assume there are multiple threads. Even if your own code doesn't create new threads, there can be cases where multiple threads are calling your code (such as in a servlet container, where the container manages a threadpool and allocates a thread to each incoming request).
A class does not need to extend Thread or implements Runnable to mark it's method as synchronized to protect from multiple thread access
Your class may a parameter to some other thread class and that thread class may have multiple instances. To provide strong consistency of data, you have protect your critical section of code & data.
Just change your code example as below.
I am demonstrating "synchronized" at object level rather than class level ( static synchronized)
class Test {
private int count = 0;
public void incrementCount() {
count++;
System.out.println("Count:"+count);
}
}
class MyRunnable implements Runnable{
private Test test = null;
public MyRunnable(Test t){
this.test = t;
}
public void run(){
test.incrementCount();
}
}
public class SynchronizedDemo{
public static void main(String args[]){
Test t = new Test();
for ( int i=0; i<10; i++){
new Thread(new MyRunnable(t)).start();
}
}
}
Your class Test has been passed as a parameter to thread MyRunnable. Now you have created multiple instances of threads. In absence of synchronized keyword, the output is unpredictable as follows.
java SynchronizedDemo
Count:2
Count:3
Count:2
Count:7
Count:6
Count:5
Count:4
Count:10
Count:9
Count:8
If I change
public void incrementCount() {
to
public synchronized void incrementCount() {
the output is:
Count:1
Count:2
Count:3
Count:4
Count:5
Count:6
Count:7
Count:8
Count:9
Count:10
On a different note, you have make your method as static synchronized. That means lock is maintained at class level instead of object level.
Have a look at oracle documentation page for better understanding.
Demo of code for absence of "static synchronized"
class Test {
private static int count = 0;
public static void incrementCount() {
count++;
System.out.println("Count:"+count);
}
}
class MyRunnable implements Runnable{
private Test test = null;
public MyRunnable(Test t){
this.test = t;
}
public void run(){
test.incrementCount();
}
}
public class SynchronizedDemo{
public static void main(String args[]){
for ( int i=0; i<10; i++){
Test t = new Test();
new Thread(new MyRunnable(t)).start();
}
}
}
output:
Count:5
Count:4
Count:3
Count:2
Count:10
Count:9
Count:8
Count:7
Count:6
After making
public static void incrementCount() {
to
ppublic static synchronized void incrementCount() {
output:
Count:1
Count:2
Count:3
Count:4
Count:5
Count:6
Count:7
Count:8
Count:9
Count:10
In this example, unlike earlier, we have created 10 different Test instances.
i++, even though it looks like a single instruction, is actually multiple instructions:
Set a temporary variable to 1+i.
Set the variable i to the temporary variable.
However, suppose the thread that executes i++ is interrupted after step 1, and the interrupting thread also calls i++. Then, this would happen:
(Suppose i=1)
Original thread: set temporary variable1 to 1+i, or 2.
Interrupting thread: set temporary variable2 to i+1, also 2
Interrupting thread: set i to temporary variable2. Now i=2
Original thread: set i to temporary variable1. Now i=2
The problem is that if i++ is called twice, it should be 3, not 2.
A synchronized void would put a lock on the variable i until the entire void completes executing. For example:
Original thread: set temporary variable1 to 1+i, or 2. Puts a lock on the variable i.
Interrupting thread: TRIES TO set temporary variable2 to i+1, but waits because of the lock on variable i
Original thread: set i to temporary variable1. Now i=2. The variable i is now unlocked.
Interrupting thread: "notices" that i has been unlocked, so it sets temporary variable2 to i+1 which is 3.
Interrupting thread: sets i to 3, which is expected behavior.
synchronized voids essentially lock variables temporarily to avoid confusing the program's execution.

long and double assignments are not atomic - How does it matter?

We know that long and double assignments are not atomic in Java until they are declared volatile. My question is how does it really matter in our programming practice.
for instance if you the see below classes whose objects are being shared among multiple threads.
/**
* The below class is not thread safe. the assignments to int values would be
* atomic but at the same time it not guaranteed that changes would be visible to
* other threads.
**/
public final class SharedInt {
private int value;
public void setValue(int value) {
this.value = value;
}
public int getValue() {
return this.value;
}
}
Now consider another SharedLong
/**
* The below class is not thread safe because here the assignments to long
* are not atomic as well as changes are not
* guaranteed to be visible to other threads.
*/
public final class SharedLong {
private long value;
public void setValue(long value) {
this.value = value;
}
public long getValue() {
return this.values;
}
}
Now we can see the both of the above versions are not thread safe. In case of int, it is because threads may see stale values of integer. While in case if long, they can see corrupt as well as stale values of long variable.
In both cases, if an instance is not shared among multiple threads, then the classes are safe.
To make the above classes thread safe we need to declare int and long both to be volatile or make the method synchronized.
This make me wonder: How does it really matter if assignments to long and double are not atomic during our normal course of programming because both need to be declared volatile or synchronized for multithreaded access so my Questions is What are the scenarios where the fact that long assignments are not atomic may make a difference?.
I made a cool little example of this a while ago
public class UnatomicLong implements Runnable {
private static long test = 0;
private final long val;
public UnatomicLong(long val) {
this.val = val;
}
#Override
public void run() {
while (!Thread.interrupted()) {
test = val;
}
}
public static void main(String[] args) {
Thread t1 = new Thread(new UnatomicLong(-1));
Thread t2 = new Thread(new UnatomicLong(0));
System.out.println(Long.toBinaryString(-1));
System.out.println(pad(Long.toBinaryString(0), 64));
t1.start();
t2.start();
long val;
while ((val = test) == -1 || val == 0) {
}
System.out.println(pad(Long.toBinaryString(val), 64));
System.out.println(val);
t1.interrupt();
t2.interrupt();
}
// prepend 0s to the string to make it the target length
private static String pad(String s, int targetLength) {
int n = targetLength - s.length();
for (int x = 0; x < n; x++) {
s = "0" + s;
}
return s;
}
}
One thread constantly tries to assign 0 to test while the other tries to assign -1. Eventually you'll end up with a number that's either 0b1111111111111111111111111111111100000000000000000000000000000000 or 0b0000000000000000000000000000000011111111111111111111111111111111. (Assuming you aren't on a 64 bit JVM. Most, if not all, 64 bit JVMs will actually do atomic assignment for longs and doubles.)
Where improper programming with an int may result in stale values being observed, improper programming with a long may result in values that never actually existed being observed.
This could theoretically matter for a system that only needs to be eventually-correct and not point-in-time correct, so skipped synchronization for performance. Although skipping a volatile field declaration in the interest of performance seems on casual inspection like foolishness.
It makes a difference if SharedInt or SharedLong are going to be accessed simultaneously. As you said, one thread may read a stale int, or a stale or corrupted long.
This could be important if the value was being used to reference an array.
Or with display in a GUI.
How about writing some values over a network and sending bad data. Now clients are confused or crashing.
Incorrect values could be stored to a database.
Repeated calculations could be corrupted...
As you requested in comments, For long specifically:
Long values are frequently used for time calculations. This could throw off loops where you are waiting for an amount of time before performing some operation, such as a heartbeat in a networking app.
You could report to a client synchronizing clocks with you time was 80 years or 1000 years in the past.
Longs and ints are commonly used for bitpacked fields to indicate many different things. Your flags would be entirely corrupted.
Longs are used as unique ID's frequently. This could corrupt hash tables you're creating.
Obviously lots of bad, bad stuff could happen. If this value needs to be thread safe, and you want your software to be very reliable, declare these variables volatile, use an Atomic variable, or synchronize access and set methods.

Categories