How synchronization helps in variable visibility? - java

public class NoVisibility {
private static boolean ready;
private static int number;
private static class ReaderThread extends Thread {
public void run() {
while (!ready)
Thread.yield();
System.out.println(number);
}
}
public static void main(String[] args) {
new ReaderThread().start();
number = 42;
ready = true;
}
}
According to "Java Concurrency in Practice", it may be possible that it will print 0 as write to ready might be made visible to the reader thread before write to a number or program never terminate at all because it does not use adequate synchronization. It is not guaranteed that values of ready and number written by main thread will be visible to reader thread.
How is it possible? Program will be run sequentially by a thread and it first writes to number and then ready variable. Isn't it? And how can this program could loop forever?

There are no guarantees that by changing a variable in one thread, other threads will see the results of those changes. Technically there is no happens-before relation between them and thus no guarantees (whilst in practice you'll see the changes almost all the time).
That's why the thread may run forever.
Secondly, why sometimes 0 ?
Well the JLS says that
Writes in one thread that are in a data race with reads in another
thread may, for example, appear to occur out of order to those reads.
Which means that your
number = 42;
ready = true;
Can occur in any order. Now it's more likely they'll appear in order, but again there's no guarantees.
You could fix it by changing the variables to be volatile, in which case the writes will always be visible to the readers or by making the code where you mutate state a critical section (see the book). In general I feel using too many volatile variables is a bit of a hack, so you should try and use them sparingly, for things like thread "running" variables.
public class NoVisibility {
private static volatile boolean ready;
private static volatile int number;
private static class ReaderThread extends Thread {
public void run() {
while (!ready)
Thread.yield();
System.out.println(number);
}
}
public static void main(String[] args) {
new ReaderThread().start();
number = 42;
ready = true;
}
}

If ready is not marked as 'volatile' than the ReaderThread might check its value (as 0).
It later does not check again about ready's value because it assume it has not changed.
The volatile keyword instructs the compiler not to have such assumptions at all and that the variable's value might change under his feet.

Related

synchronized keyword in Java threads

I am trying to see how multithreading(particularly with synchronized keyword) works.In this example I want the second thread abc1 to start executing after thread abc. So I've used synchronized keyword in run function.But the output line which says:
Initial balance in this thread is 10000
Initial balance in this thread is 10000
is what concerns me.Because the initial balance should be "-243000" as indicated in output line
Final balance after intial -243000 is 59049000
because the abc1 thread should wait for abc due to synchronized keyword.
Primarily , I want the threads to behave as if I write
abc.start
abc.join()
abc1.start()
abc1.join()
Here is my source code:
class parallel extends Thread{
account a;
public parallel(account a) {
this.a=a;
}
public synchronized void run() {
synchronized(this) {
System.out.println("Initial balance in this thread is "+a.amount);
long duplicate=a.amount;
boolean flag=true;
//System.out.println("Transaction inititated");
for(int i=0;i<10;i++) {
if(flag==true) {
//System.out.println("Deducting "+amount+"Rs from your account");
a.amount-=a.amount*2;
}
else {
//System.out.println("Depositing "+amount+"Rs from your account");
a.amount+=a.amount*2;
}
flag=!flag;
}
System.out.println("Final balance after intial "+duplicate+" is "+a.amount);
syncro.amount=a.amount;
}
}
}
class account{
public account(long rupe) {
amount=rupe;
}
long amount;
}
public class syncro {
static long amount;
public static void main(String[] args) throws InterruptedException{
//for(int i=0;i<10;i++) {
account ramesh=new account(1000);
parallel abc=new parallel(ramesh);
parallel abc1=new parallel(ramesh);
abc.start();
//abc.join();
abc1.start();
//abc1.join();
//}
//awaitTermination();
//Thread.sleep(4000);
boolean ab=true;
long cd=1000;
for(int i=0;i<10;i++) {
if(ab==true) {
//System.out.println("Deducting "+ab+"Rs from your account");
cd-=cd*2;
}
else {
//System.out.println("Depositing "+a+"Rs from your account");
cd+=cd*2;
}
ab=!ab;
}
//System.out.println("Final amount by multithreading is "+);
System.out.println("Final amount after serial order is "+cd);
}
}
You are mixing the creating of your own threads with the use of synchronized. Also, using synchronized(this) within a synchronized method is doing the same thing twice.
Synchronized is NOT about starting threads. It is about allowing only one thread to enter a certain block of code at a time.
Every object you create has a hidden field that you cannot read, but it does exist. It is of type Thread and it is called owner.
The synchronized keyword interacts with this hidden field.
synchronized (object) {
code();
}
means the following:
If object.owner == Thread.currentThread(), then just keep going and increment a counter.
If object.owner == null, then run object.owner = Thread.currentThread(), set that counter to 1, and keep going.
Otherwise (So, object.owner is some other thread), stop, freeze the thread, and wait around until the owner is set to null, and then we can go to option #2 instead.
Once we're in, run code(). When we get to the closing brace, decrement the counter. If it is 0, run object.owner = null.
Furthermore, all the above is done atomically - it is not possible for 2 threads to get into a race condition doing all this stuff. For example, if 2 threads are waiting for owner to become unset again, only one will 'get it', and the other will continue waiting. (Which one gets it? A VM impl is free to choose whatever it wants; you should assume it is arbitrary but unfair. Don't write code that depends on a certain choice, in other words).
A method that is keyworded with synchronized is just syntax sugar for wrapping ALL the code inside it in synchronized(this) for instance methods and synchronized(MyClass.this) for static methods.
Note that synchronized therefore only interacts with other synchronized blocks, and only those blocks for which the object in the parentheses is the exact same obj reference, otherwise none of this does anything. It certainly doesn't start threads! All synchronized does is potentially pause threads.
In your code, you've put ALL the run code in one gigantic synchronized block, synchronizing on your thread instance. As a general rule, when you synchronize on anything, it's public API - other code can synchronize on the same thing and affect you. Just like we don't generally write public fields in java, you should not lock on public things, and this is usually public (as in, code you don't control can hold a reference to you). So don't do that unless you're willing to spec out in your docs how your locking behaviours are set up. Instead, make an internal private final field, call it lock, and use that (private final Object lock = new Object();).

While loops do not terminate when condition is satisfied

To my understanding the following code should terminate normally as the condition stopRunning = true; is met.
However, when I run this program it is printing only Last line of Main(), Start Method ended is never printed as the while loop is never terminated.
public class Test {
private static boolean stopRunning = false;
public static void main(String[] args) throws Exception {
new Thread(new Runnable() {
#Override
public void run() {
start();
}
}).start();
Thread.sleep(100);
stopRunning = true;
System.out.println("Last line of Main()");
}
public static void start() {
while (!stopRunning) {
}
System.out.println("Start Method ended.");
}
}
Please help me understand this behavior.
Changing the flag to volatile with
private static volatile boolean stopRunning = false;
will mean that other threads see the change immediately (from main memory instead of a cache), and the code executes as you expect. How volatile relates to Java's memory model is explained further e.g. in this tutorial.
As Mick stated, you should use the volatile keyword to synchronize your variable, so on a change the new value is written directly back to memory and your code will work as expected.
Be aware (also stated in the article Mick linked) that volatile does not guarantee to avoid race conditions, so if two different threads would read your variable, it is not safe that they both read the same value (despite everything is read from memory and on change directly written back)
As stated in previous answers:
Like Mike stated - in run() you should use Test.start() or rename the method. The start you are calling is the thread's start method.
Also as Mick stated, setting stopRunning as volatile should help. The reason it should work is that it will remove the caching of the variable in the thread's memory and will get/set directly from memory.

Volatile variables - Java Concurrency in Practice [duplicate]

Ok so I just read this question Do you ever use the volatile keyword in Java?, and I get using a volatile variable in order to stop a loop. Also I've seen this reference, http://www.javamex.com/tutorials/synchronization_volatile.shtml. Now the article says that volatile variables are non-blocking. Also it says that it cannot be used for concurrency in a read-update-write sequence. Which makes sense because they're non-blocking.
Since volatile variables are never cached is it faster to simply use synchronization to stop the loop (from the earlier link)?
Edit: Using a synchronized solution
public class A{
private boolean test;
public A(){
test = true;
}
public synchronized void stop(){
test = false;
}
public synchronized boolean isTrue(){
return test;
}
}
public class B extends Thread {
private A a;
public B(A refA){
a = refA;
}
public void run(){
//Does stuff here
try{
sleep(1000);
}
catch(Exception e){}
a.stop();
}
public static void main(String [] args){
A TestA = new A();
B TestB = new B(TestA);
TestB.start();
while(TestA.isTrue()){
//stay in loop
System.out.println("still in loop");
}
System.out.println("Done with loop");
}
}
No, reading a volatile variable is faster than than reading an non-volatile variable in a synchronized block.
A synchronized block clears the cached values on entry which is the same as reading a volatile variable. But, it also flushes any cached writes to main memory when the synchronized block is exited, which isn't necessary when reading volatile variable.
There's a numebr of things wrong in your question: You can do a reliable read-update-write with volatile so long as you use Atomic*FieldUpdater and a cas-loop. Volatiles can be "cached", they just need to obey the relevant happens-before semantics specified.
Synchronisation typically involves obtaining a lock, which is relatively expensive (although may actually be quite cheap). Simple concurrent optimisations may use non-naive implementation techniques.

Using ThreadLocal in tandem with Volatile gives unpredictable results

I was reading through Java Memory model and was playing with volatile. I wanted to check how Volatile will work in tandem with ThreadLocal. As per definition ThreadLocal has its own, independently initialized copy of the variable whereas when you use volatile keyword then JVM guarantees that all writes and subsequent reads are done directly from the memory. Based on the high level definitions i knew what i was trying to do will give unpredictable results. But just out of curiosity wanted to ask if someone can explain in more details as if what is going on in the background. Here is my code for your reference...
public class MyMainClass {
public static void main(String[] args) throws InterruptedException {
ThreadLocal<MyClass> local = new ThreadLocal<>();
local.set(new MyClass());
for(int i=0;i<5; i++){
Thread thread = new Thread(local.get());
thread.start();
}
}
}
public class MyClass implements Runnable {
private volatile boolean flag = false;
public void printNameTillFlagIsSet(){
if(!flag)
System.out.println("Flag is on for : " + Thread.currentThread().getName());
else
System.out.println("Flag is off for : " + Thread.currentThread().getName());
}
#Override
public void run() {
printNameTillFlagIsSet();
this.flag = true;
}
}
In your code you create a ThreadLocal reference as a local variable of your main method. You then store an instance of MyClass in it and then give that same reference of MyClass to 5 threads created in the main method.
The resulting output of the program is unpredictable since the threads are not synchronized against each other. At least one thread will see the flag as false the other four could see the flag as either true or false depending on how the thread execution is scheduled by the OS. It is possible that all 5 threads could see the flag as false, or 1 could see it false and 4 see it true or anything in between.
The use of a ThreadLocal has no impact on this run at all based on the way you are using it.
As most have pointed out you have deeply misunderstood ThreadLocal. This is how I would write it to be more accurate.
public class MyMainClass {
private static final ThreadLocal<MyClass> local = new ThreadLocal<>(){
public MyClass initialValue(){
return new MyClass();
}
}
public static void main(String[] args) throws InterruptedException {
local.set(new MyClass());
for(int i=0;i<5; i++){
Thread thread = new Thread(new Runnable(){
public void run(){
local.get().printNameTillFlagIsSet();
local.get().run();
local.get().printNameTillFlagIsSet();
}
});
thread.start();
}
}
}
So here five different instances of MyClass are created. Each thread will have their own accessible copy of each MyClass. That is Thread created at i = 0 will always have a different instance of MyClass then i = 1,2,3,4 despite how many local.get() are done.
The inner workings are a bit complicated but it can be done similar to
ConcurrentMap<Long,Thread> threadLocalMap =...;
public MyClass get(){
long id = Thread.currentThread().getId();
MyClass value = threadLocalMap.get(id);
if(value == null){
value = initialValue();
threadLocalMap.put(id,value);
}
return value;
}
To further answer your question about the volatile field. It is in essence useless here. Since the field itself is 'thread-local' there will be no ordering/memory issues that can occur.
Just don't divinize the JVM. ThreadLocal is a regular class. Inside it uses a map from current thread ID into an object instance. So that the same ThreadLocal variable could have its own value for each thread. That's all. Your variable exists only in the main thread, so it doesn't make any sence.
The volatile is something about java code optimization, It just stops all possible optimizations which allow avoid redundant memory reads/writes and execution sequence re-orderings. It is important for expecting some particular behaviour in multi-threaded environment.
You have two big problems:
1) As many pointed out, you are not using ThreadLocal properly so you don't actually have any "thread local" variables.
2) Your code is equivalent to:
MyClass someInstance = new Class();
for (...)
... new Thread(someInstance);
so you should expect to see 1 on and 4 off. However your code is badly synchronized, so you get random results. The problem is that although you declare flag as volatile, this is not enough for good synchronization since you do the check on flag in printNameTillFlagSet and then change the flag value just after that method call in run. There is a gap here where many threads can see the flag as true. You should check the flag value and change it within a synchronized block.
You main thread where you have a ThreadLocal object is being passed to all the threads. So the same instance is being passed.
So its as good as
new Thread(new MyClass());
What you could try is have an object being called by different threads with a thread local variable. This will be a proper test for ThreadLocal where each thread will get its own instance of the variable.

Java volatile for concurrency

Ok so I just read this question Do you ever use the volatile keyword in Java?, and I get using a volatile variable in order to stop a loop. Also I've seen this reference, http://www.javamex.com/tutorials/synchronization_volatile.shtml. Now the article says that volatile variables are non-blocking. Also it says that it cannot be used for concurrency in a read-update-write sequence. Which makes sense because they're non-blocking.
Since volatile variables are never cached is it faster to simply use synchronization to stop the loop (from the earlier link)?
Edit: Using a synchronized solution
public class A{
private boolean test;
public A(){
test = true;
}
public synchronized void stop(){
test = false;
}
public synchronized boolean isTrue(){
return test;
}
}
public class B extends Thread {
private A a;
public B(A refA){
a = refA;
}
public void run(){
//Does stuff here
try{
sleep(1000);
}
catch(Exception e){}
a.stop();
}
public static void main(String [] args){
A TestA = new A();
B TestB = new B(TestA);
TestB.start();
while(TestA.isTrue()){
//stay in loop
System.out.println("still in loop");
}
System.out.println("Done with loop");
}
}
No, reading a volatile variable is faster than than reading an non-volatile variable in a synchronized block.
A synchronized block clears the cached values on entry which is the same as reading a volatile variable. But, it also flushes any cached writes to main memory when the synchronized block is exited, which isn't necessary when reading volatile variable.
There's a numebr of things wrong in your question: You can do a reliable read-update-write with volatile so long as you use Atomic*FieldUpdater and a cas-loop. Volatiles can be "cached", they just need to obey the relevant happens-before semantics specified.
Synchronisation typically involves obtaining a lock, which is relatively expensive (although may actually be quite cheap). Simple concurrent optimisations may use non-naive implementation techniques.

Categories

Resources