Following are just three "happens-before" rules of JMM. I am not listing the other rules as my question is related to these three rules only.
Monitor lock rule. An unlock on a monitor lock happens before every
subsequent lock on that same monitor lock.
Thread start rule. A call to Thread.start on a thread happens before
every action in the started thread.
Interruption rule. A thread calling interrupt on another thread
happens before the interrupted thread detects the interrupt (either
by having InterruptedException thrown, or invoking isInterrupted or
interrupted).
Questions
1st rule question - Let's say two threads A and B have synchronized blocks of code. Does the first rule mean that any variable set in a synchronized block in thread A, will be visible to the code in synchronized block of thread B, even if the variable is NOT declared as volatile?
2nd rule question - Let's say a thread A starts a thread B. Does the second rule mean that any variable set in a parent thread before calling start() will be visible to thread B even if the variable is NOT declared as volatile?
3rd rule question - Let's say a thread A interrupts a thread B. Does the third rule mean that any variable set in thread A before interrupting thread B will be visible to thread B after the interrupt is detected, even if the variable is not declared as volatile?
Finally, one more question:
In BlockingQueue documentation, it is said,
Memory consistency effects: As with other concurrent collections, actions in a >thread prior to placing an object into a BlockingQueue happen-before actions >subsequent to the access or removal of that element from the BlockingQueue in >another thread.
Does this mean any variable set in a thread A before enqueuing an object in the blocking queue will be visible to thread B after dequeuing the object from the queue, even if the variable is NOT declared as volatile?
Basically through the above questions, I am trying to understand if the memory flush happens after these events such that the variables need not be declared as volatile in these cases.
1st rule question - Let's say two threads A and B have synchronized blocks of code.
Threads don't have code. Threads execute code.
Does the first rule mean that any variable set in a synchronized block in thread A, will be visible to the code in synchronized block of thread B, even if the variable is NOT declared as volatile?
Yes, Suppose we have:
private int i;
private final Object lock = new Object();
void foobar(...) {
...
synchronized(lock) {
i = ...;
}
}
int getI() {
synchronized(lock) {
return i;
}
}
If thread A calls foobar(), and then thread B subsequently calls getI(), then thread B will get the new value of i.
But note! My example above does not include any way for you to prove which call actually happened first. If your program depends on those calls to happen in a particular order, then it's going to need more than just a mutex: It's going to need some means to make thread B wait() for thread A to perform the update.
2nd rule question - Let's say a thread A starts a thread B. Does the second rule mean that any variable set in a parent thread before calling start() will be visible to thread B even if the variable is NOT declared as volatile?
Yes, that's what it means.
3rd rule question...
Yes again.
... BlockingQueue ...
Yes again.
...Through the above questions, I am trying to understand if the memory flush happens after these events such that...
Don't even think about "memory flush". That is not part of the Java language: If it happens, it's an implementation detail, and you don't need to worry about it unless you are implementing a JVM.
The only concept you need to worry about is the "happens before".
Whenever the JLS says that A happens before B, it means that if A happens in thread 1, and B happens in thread 2, and you can prove that A actually did happen before B in real-time, then any field that was updated by thread 1 before A happened will be guaranteed visible in thread 2 after B happens.
Related
Let's say we have 'class A' which has a data member 'var'.
class A
{
int var;
method()
{
read(var);
synchronized block
{
update var here;
}
}
Let's say Thread 1 acquires the lock and enters the synchronized block. It updates the field value 'var'. Let's say the field value is cached in the processor's core by the Thread. It updates the value in the cache.
Now thread 2 starts running, enters method(), and reads field value 'var'.
Wil thread 2, surely get the updated value? Does synchronize makes sure thread 2 will get updated value even when Thread 1 has not exited Synchronized. In this case, do we need to make 'var' volatile?
PS - Everything is happening on the same object.
If you would not make 'var' volatile, then there is no happens-before edge between writing and reading 'var'. So you have a data race on your hands and weird things can happen like the compiler messing things up.
So in short: make it volatile (or make sure you read 'var' using the same lock).
Does synchronize makes sure thread 2 will get updated value
No. synchronized doesn't do anything for a thread if the thread does not enter a synchronized block. The way to think about synchronized is this: Whatever one thread does before it leaves a synchronized block is guaranteed to become visible to some other thread by the time the second thread subsequently* enters a block that is synchronized on the same lock object.
For a single int variable, you could make it volatile instead. volatile makes a guarantee similar to the guarantee of synchronized: Whatever one thread does before it updates a volatile variable is guaranteed to become visible to some other thread by the time the second thread subsequently* reads the same volatile variable.
* Edit: I added "subsequently" to make it clear that neither synchronized nor volatile is sufficient to ensure that the threads will access var in some particular order. If you wish to ensure that thread 2 will not try to read var until after thread 1 has assigned it, then you will have to use some other means† to coordinate their activity. Correct use of synchronized or volatile only can ensure that IF thread 1 updates var before thread 2 examines it, then thread 2 will see the update.
† There are many "other means." One example is a Semaphore. Thread 1 could release() a permit to the semaphore after it updates var, and thread 2 could acquire() the permit before it reads var. The acquire() call would cause thread 2 to wait if it arrived at the semaphore before thread 1 had done its job.
I am learning about cooperation between concurrent tasks and I have got that question and a possible answer to it. I would like to make sure I understand it correctly.
So to call a.wait() it is first required to synchronize on the object a or to be more precise a thread must become the owner of the a's monitor. As far as I understand, the only reason why a.wait() should be called in a synchronized context (together with a.notify()/a.notifyAll()) is to avoid a race condition/The Lost Wake-Up Problem. But theoretically, it is possible to avoid the race condition calling a.wait(),a.notify()/a.notifyAll() by synchronizing on some other object, like this:
Thread #1:
synchronized(b) {
…
a.wait(); // here a thread owns only one monitor: the monitor of the object stored in the variable b, where a != b
…
}
Thread #2:
synchronized(b) {
…
a.notify(); // the same here
…
}
The expected behavior is: the thread #1 acquires the monitor of b, enters the critical section, invokes a.wait(), then waits on a and releases the monitor of b. Afterwards the thread #2 acquires the monitor of b, enters the critical section, invokes a.notify() (the thread #1 gets notified), exits the critical section and releases the monitor of b, then the thread #1 acquires the monitor of b again and continues running. Thus, only one critical section synchronized on b can run at a time and no race condition can occur. You may ask, “but how would wait() know that the object b is used in this case to avoid the race condition and thus its monitor must be released?”. Well, that way it wouldn’t know. But maybe the wait method could take an object as an argument to know which object’s monitor to release, for example, a.wait(b), to wait on a and release the monitor of b. But there is no such an option: a.wait() causes a thread to wait on a and releases the monitor of exactly the same a. Period. The invocation of the wait and notify methods in the code above results in IllegalMonitorStateException.
According to this information from the Wikipedia article, the functionality of the wait, notify/notifyAll methods is built into every object's monitor where it is integrated into the functionality of the synchronization mechanism at the level of every individual object. But still it doesn't explain why it was done this way in the first place.
My answer to the question: before calling the wait method of an object, a thread should own the monitor of exactly the same object because to avoid a race condition this object is always not only a viable option but the best one.
Let’s see if there are any situations where it could be undesirable to synchronize on an object before invoking its wait, notify/notifyAll methods (plus some relevant logic). Synchronizing on the object would block it for other threads which could be undesirable if the object has some other synchronized methods (and/or there are some critical sections synchronized on the object) having nothing to do with the waiting logic. In that case it is always possible to refactor the corresponding class(es) so that the wait and notify/notifyAll methods operate on one object, while other synchronized methods/blocks operate on another one(s). For example, one of possible solutions could be creating a dedicated object specifically for a waiting logic (to wait and synchronize on) like in the example below:
public class A {
private Object lock = new Object(); // an object to synchronize and wait on for some waiting logic
private boolean isReady = false;
public void mOne() throws InterruptedException {
synchronized(lock) { // it blocks the instance of the Object class stored in the variable named lock
while(!isReady) {
lock.wait();
}
}
}
public void mTwo() {
synchronized(lock) { // the same here
isReady = true;
lock.notify();
}
}
synchronized public void mThree() { // it blocks an instance of A
// here is some logic having nothing to do with the above waiting and
// mThree() can run concurrently with mOne() and mTwo()
}
}
So there is no need to synchronize on some voluntary object to avoid a certain race condition regarding calling wait, notify/notifyAll methods. If it was allowed it would only cause unnecessary confusion.
Is it correct? Or maybe I am missing something here. I would like to make sure I don't miss anything important.
Oracle documentation: wait, notify, notifyAll
I know that volatile keyword refresh all the invisible data i.e. if some thread read volatile variable all potential invisible variables/references (not only the variable that will be read) will be okey(visible i.e. with correct values) after this reading. Right? But what about synchronized ? Is it the same ? If in synchronized block we read 3 variables for example will all other varibles will be visible?
What will hapen if one thread change the value of some variable (for example set varible "age" from 2 to 33) from non-synchronized block and after this thread die ? The value could be written in the thread stack, but main thread maybe will not see this change, the background thread will die and the new value is gone and can not be retrieved?
And last question if we have 2 background threads and we know that our main thread will be notified (in some way) just before every one of them will die and our thread will wait both of them to finish their work and will continue after that, how we can assure that all variables changes(which are made by the background threads) will be visible to the main thread? We can just put synchronized block after the background thread finishes or ? We don't want to access variables that are changed from the background threads with synchronized blocks every time after this threads are dead (because it's overhead), but we need to have their right values ? But it is unnatural to read some fake volatile variable or to use fake synchronized block(if it refresh all data) just to refresh all data.
I hope that my questions are explained well.
Thanks in advance.
Reading the value of a volatile variable creates a happens-before relationship between the writing from one thread and the reading of another.
See http://jeremymanson.blogspot.co.uk/2008/11/what-volatile-means-in-java.html:
The Java volatile modifier is an example of a special mechanism to
guarantee that communication happens between threads. When one thread
writes to a volatile variable, and another thread sees that write, the
first thread is telling the second about all of the contents of memory
up until it performed the write to that volatile variable.
Synchronized blocks create a happens-before relationship as well. See http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html
An unlock (synchronized block or method exit) of a monitor
happens-before every subsequent lock (synchronized block or method
entry) of that same monitor. And because the happens-before relation
is transitive, all actions of a thread prior to unlocking
happen-before all actions subsequent to any thread locking that
monitor.
Which have the same effect on visibility.
If a value is written without any kind of synchronization then there is no guarantee that other threads will ever see this value. If you want to share values across threads, you should be adding some kind of synchronization or locking, or using volatile.
All your questions are answered in the java.util.concurrent package documentation.
But what about synchronized?
Here's what the documentation says:
An unlock (synchronized block or method exit) of a monitor happens-before every subsequent lock (synchronized block or method entry) of that same monitor. And because the happens-before relation is transitive, all actions of a thread prior to unlocking happen-before all actions subsequent to any thread locking that monitor.
.
The value could be written in the thread stack, but main thread maybe will not see this change, the background thread will die and the new value is gone and can not be retrieved?
If the value is written in the thread stack, then we're talking about a local variable. Local variable are not accessible anywhere except in the method declaring that variable. So if the thread dies, of course the stack doesn't exist and the local variable doesn't exist either. If you're talking about a field of an object, that's stored on the heap. If no other thread has a reference to this object, and if the reference is unreachable from any static variable, then it will be garbage collected.
and our thread will wait both of them to finish their work and will continue after that, how we can assure that all variables changes(which are made by the background threads) will be visible to the main thread
The documentation says:
All actions in a thread happen-before any other thread successfully returns from a join on that thread.
So, since the main thread waits for the background threads to die, it uses join(), and every action made by the background threads will be visible by the main thread after join() returns.
Fully covering the whole topic from the level your question seems to imply will require more than a StackOverflow.com answer, so I recommend looking for a good book on multi threading programming.
volatile guarantee that the read and write accesses to the qualified variable are totally ordered with respect to other accesses to the samevolatile variable1.
It does this by preventing the volatile read and write accesses to be reorder with previous or future instructions and enforcing that all the side effects before the access of the writing thread are visible to a reading thread.
This means that volatile variable are read and written as you see in your code and like the instructions were executed one at a time, beginning the next one only when all the side effects of the previous are completed and visible to every other thread.
To better understand what this means and why this is necessary, look at this question of mine on difference between Memory Barriers and lock prefixed instruction.
Note that volatile in Java is much much much stronger than volatile in C or C++. It does guarantee more that the usual treating of read/write access as a side effect with regard to optimization purposes. This means that is doesn't simply imply that the variable is read from the memory every time, a Java volatile is a memory barrier.
The synchronized block simply guarantees exclusive (i.e. one thread at a time) execution of a block of code.
It doesn't imply that all the thread see the memory access is the same order, a thread could see first the write to a protected shared data structure and then the write to the lock!
1 In some circumstances, where a full memory barrier is emitted, this may enforce that writes and reads to all volatile variables made by a thread T will be visible to other threads in T program order. Note that this not suffices for synchronization as there is still no relationship between inter-thread accesses.
No.
Shared vars are not on the stack of any thread, copy of their value can be but the variables exists independently of any thread.
When a thread dies gracefully, the write is done and can be retrieved (beware of memory ordering again).
If the thread dies forcefully, it could be interrupted anywhere. In any way the actual Java assignment is implemented if the thread stops before the write to the shaded var (by direct assignment or by copying a local value on the stack) then the write never happened.
You don't need synchronized, just volatile as the main thread only reads and the background threads only write (different vars).
I have a method which is synchronized defined in some class.
We know that if we create a method as synchronized, then only one thread is able to execute the task at a time.
What is happening inside this method ?
How does other thread not able to execute the same task to run same method.
As per my knowledge, join is applied on that particular thread. But how does the second thread in the pipeline knows about the task has been done by first thread.
Tell me if i am right.
In the Java language, each Object has what is called a Monitor, which basically is a lock.
This lock is what powers Object methods such as wait / signal / signalAll that are available on every objects.
When using the synchronized keyword, what happens behind the scenes is that the compiler writes code that acquires the monitor (the lock) and releases it when invocation is complete.
If the method is static, the Monitor that is accessed is that of the Class object.
You can read more about this keyword here :
http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
One thread (first) acquires a lock on the object, and another thread waits for getting lock of that object.
Once task is done, first thread sends notification to waiting threads using notify() and notifyAll() methods.
We know that if we create a method as synchronized, then only one thread is able to execute the task at a time.
Not True! Two or more threads can enter the same synchronized block at the same time. And, that's not just in theory: It often happens in well-designed programs.
Here's what two or more threads can not do: Two or more threads can not synchronize on the same object at the same time. If you want to insure that only one thread at a time can enter a particular method (but why?†) then you need to write the method so that all calls to it will synchronize on the same object. That's easy to do if it's a static method because this:
class Foobar {
synchronized MyType baz() { ... }
}
means the same as this:
class Foobar {
MyType baz () {
synchronized (Foobar.class) { ... }
}
}
All calls to a static synchronized method synchronize on the class object that owns the method.
[what prevents two threads from synchronizing on the same object at the same time]?
The operating system. Any JVM that you would want to use for real work uses native threads to implement Java threads. A native thread is a thread that is created and managed by calls to the operating system. In particular, it's a part of the operating system known as the scheduler. I am not going to go into the details of how an operating system scheduler works---there's whole books written about that topic---but its job is to decide which threads get to run, when, and on what processor.
A typical scheduler uses queues to keep track of all of the threads that are not actually running. One special queue, the run queue, holds threads that are ready to run, but waiting for a CPU to run on. A thread on the run queue is called runnable. A thread on any other queue is blocked (i.e., not allowed to run) until something happens that causes the scheduler to put it back on the run queue.
The operating system object corresponding to a Java monitor (See #TheLostMind's answer) often is called a mutex or a lock. For each mutex, there is a queue of threads that are blocked, waiting to enter it. A native thread enters a mutex by calling the operating system. That gives the operating system the opportunity to pause the thread and add it to the mutex's queue if some other thread is already in the mutex. When a thread leaves a mutex, that's a system call too; and it gives the scheduler the opportunity to pick one thread off the mutex's queue, and put it back on the run queue.
Like I said, the details of how the scheduler does those things go way too deep to talk about here. Google is your friend.
† Don't worry about which threads can enter which method at the same time. Worry instead about which threads touch which data. The purpose of synchronization is to allow one thread to temporarily put your data into a state that you don't want other threads to see.
What is happening inside this method ?
When you say a (instance level) method is synchronized, A thread must first get a lock on the Object (i.e, first hold the monitor of that object) to access it. As long as one thread holds the lock / monitor, other threads cannot access it. because they cannot get a lock on the object (it is like door to the object).
How does other thread not able to execute the same task to run same method.
Because as long as one thread still holds the monitor, other threads wait. i.e, they cannot access the monitor themselves.So, they are blocked and will wait in the waiting set / queue for that object.
join is applied on that particular thread. But how does the second thread in the pipeline knows about the task has been done by first thread.
Join() ensures that the thread that calls join() on another thread, waits until the second thread completes its execution.
Note : A happens before relationship is established between the 2 threads when join is called. So that Whatever happens before a call to join or a return from join are always visible to other thread.
Edit :
Assume ThreadA and ThreadB are two threads running concurrently.
ThreadA
{
run(){
//some statements;
x=10; // assume x to be some shared variable
ThreadB.join();
// here ThreadA sees the value of "x" as 20. The same applies to synchronized blocks.
// Suppose ThreadA is executing in a Synchronized block of Object A, then after ThreadA //exits the synchronized block, then other threads will "always" see the changes made by //ThreadA
// some other statements
}
}
ThreadB{
run(){
//some statements
x=20;
}
check : Happens Before
Can non synchronized methods called from synchronized methods allow a thread to block?
public synchronized void foo(){
someStuff();
someMoreStuff();
bar();
}
public void bar(){
//... does some things
}
If a thread is executing foo() is there anyway to ensure that bar() will be called before the thread sleeps?
TIA
A thread can always be pre-empted (there's no way of preventing that in Java) but no other thread will be able to acquire the lock on the same object before foo returns.
Note that a thread "losing the CPU" isn't what's normally meant by "blocking" - normally a call is deemed to block if it needs to wait for something else to occur. For example:
Reading from a stream blocks until there is some data available (or the end of the stream is reached)
Acquiring a lock blocks until the lock is available
These are very different from just running out of time slice.
Are you asking if there's a way to insure that the Java VM doesn't take the CPU and let another thread execute? You could set the Thread priority to high, but this still wouldn't provide a guarantee at all.
No other thread will be able to call your "foo" method while you don't have the CPU, though. Similarly, synchronizing "bar" would prevent it from being called until your call to "foo" had completed (as you own the lock for the entire period of the "foo" method).
The question seems to be if other threads can freely invoke bar() while one thread holds the lock on an object during the execution of foo(). And specifically, if two or more threads can be running bar() at the same time.
And the answer is that any thread can run bar() at any time, so yes, there can be more than one thread running bar() at any single point in time.