I have a Thread-X which reads a non-volatile variable every second, doing so without any means of synchronization.
Now I was wondering is there some way to modify that non-volatile variable on Thread-Y such that Thread-Y's write would be (eventually) visible on Thread-X ?
public class Test {
private static boolean double = 1; // this variable is
// strictly not volatile
public static void main(String args[]) {
new java.lang.Thread(new java.lang.Runnable() {
@Override
public void run() {
while (true) {
System.out.println(variable);
try {
java.lang.Thread.currentThread().sleep(1000);
} catch (java.lang.InterruptedException e) {
}
}
}
}).start(); // line 17
new java.lang.Thread(new java.lang.Runnable() {
@Override
public void run() {
// the task is to change variable to "2" such the write
// is (eventually) registered by the other threads
// allowed to use any synchronization/locking techniques
// required, but line 1 to line 17 must not be changed
}
}).start();
}
}
Is it possible to modify a non-volatile variable such that another thread which reads it without any synchronization techniques (raw read) is able to "see" the update eventually?
Background:
I need to read a variable from a large number of threads, for an infinite amount of times.
From what I understand (correct me if I'm wrong), on most cpus (e.g. x86) reads of volatile variables are "almost totally free" but not "totally free".
Now since I have an infinite number of reads from an infinite number of threads, I would love the variable to be non-volatile. However, once in a blue moon the variable needs to be updated. In my use-case, it really doesn't matter how expensive it takes to update that variable, but that update must eventually be readable by the reader-threads.
Solutions:
Based on Tomasz's comment, I've built this solution and I was wondering is Solution-1 flawed or is it solid?
public class Solution1 {
private static double variable = 1; // this variable is
// strictly not volatile
public static void main(String args[]) {
new java.lang.Thread(new java.lang.Runnable() {
@Override
public void run() {
while (true) {
System.out.println(variable);
try {
java.lang.Thread.currentThread().sleep(1000);
} catch (java.lang.InterruptedException e) {
}
}
}
}).start(); // line 17
new java.lang.Thread(new java.lang.Runnable() {
@Override
public void run() {
variable = 2;
// writer-thread now terminates,
// is it guaranteed that when it
// "terminates successfully", variable
// is updated on the reader-thread ?
}
}).start();
}
}
Based on Joonas's comment, I've built this solution and I was wondering is Solution-2 flawed or is it solid?
public class Solution2 {
private static double variable = 1; // this variable is
// strictly not volatile
private static volatile boolean lock = false;
public static void main(String args[]) {
new java.lang.Thread(new java.lang.Runnable() {
@Override
public void run() {
while (true) {
System.out.println(variable);
try {
java.lang.Thread.currentThread().sleep(1000);
} catch (java.lang.InterruptedException e) {
}
}
}
}).start(); // line 17
new java.lang.Thread(new java.lang.Runnable() {
@Override
public void run() {
variable = 2;
lock = false; // does this line guarantee
// that other threads will now
// see the update to variable (piggypacking)?
// now let's assume this thread doesn't terminate
}
}).start();
}
}