Difference between Synchronized block with wait/notify and without them? - java

If I just use synchronized, not the wait/notify methods, will it still be thread-safe?
What's the difference?

Using synchronized makes a method / block accessible by only on thread at a time. So, yes, it's thread-safe.
The two concepts are combined, not mutually-exclusive. When you use wait() you need to own the monitor on that object. So you need to have synchronized(..) on it before that. Using .wait() makes the current thread stop until another thread calls .notify() on the object it waits on. This is an addition to synchronized, which just ensures that only one thread will enter a block/method.

So after just being embarrassed in an interview question on this I decided to look it up and understand it again for 1 billionth time.
synchronized block makes the code thread safe. No doubt about that. When wait() and notify() or notifyAll() come in is where you are trying to write more efficient code. For example, if you have a list of items that multiple threads share then if u put it in synchronized block of a monitor then threads threads will constantly jump in and run the code back and forth, back and forth during context switches......even with an empty list!
The wait() is hence used on the monitor (the object inside the synchronized(..)) as a mechanism to to tell all threads to chill out and stop using cpu cycles until further notice or notifyAll().
so something like:
synchronized(monitor) {
if( list.isEmpty() )
monitor.wait();
}
...somewhere else...
synchronized(monitor){
list.add(stuff);
monitor.notifyAll();
}

Making method as synchronized has two effects:
First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object
Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.
synchronization help you to guard the critical code.
If you want to establish communication between multiple threads, you have to use wait() and notify()/notifyAll()
wait(): Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.
notify(): Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened.
notifyAll():Wakes up all threads that are waiting on this object's monitor. A thread waits on an object's monitor by calling one of the wait methods.
Simple use case for using wait() and notify() : Producer and Consumer problem.
Consumer thread has to wait till Producer thread produce data. wait() and notify() are useful in above scenario. Over a period of time, better alternatives have been introduced. Refer to this high level concurrency tutorial page.
In simple terms:
Use synchronized to guard protect critical section of your data and guard your code.
Use wait() and notify() along with synchronization if you want to establish communication between multiple threads in safe manner, which are interdependent on each other.
Related SE questions:
What does 'synchronized' mean?
A simple scenario using wait() and notify() in java

Effective Java item 69: "Given the difficulty of using wait and
notify correctly, you should use the higher-level concurrency utilities instead."
Avoid using wait() and notify(): use synchronized, or other utilities from java.util.concurrent, when possible.

Synchronised block is used, if 2 threads of "same object" tries to accquire the lock. Since object class holds the lock, it knows who to give.
Whereas, if 2 threads(say t2 and t4) of 2 objects( t1 & t2 of obj1 and t3 & t4 of obj 2) try to acquire the lock, obj1 would be unaware of obj2's lock and obj2 would be unaware of obj1's lock. Hence wait and notify methods are used.
eg:
//example of java synchronized method
class Table{
synchronized void printTable(int n){//synchronized method
for(int i=1;i<=5;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}
class MyThread1 extends Thread{
Table t;
MyThread1(Table t){
this.t=t;
}
public void run(){
t.printTable(5);
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
public class TestSynchronization2{
public static void main(String args[]){
Table obj = new Table();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
Two threads t1 and t2 belongs to same object, hence synchronization works fine here.
Whereas,
class Table{
synchronized void printTable(int n){//synchronized method
for(int i=1;i<=5;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}
class MyThread1 extends Thread{
Table t;
MyThread1(Table t){
this.t=t;
}
public void run(){
t.printTable(5);
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
public class TestSynchronization2{
public static void main(String args[]){
Table obj = new Table();
Table obj1 = new Table();
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj1);
t1.start();
t2.start();
}
}
When you run the above program, synchronisation does not work since each thread belong to different object, Hence you should use wait and notify here.

wait/notify is required when you want to wait for some condition (e.g. user input) INSIDE a synchronized block.
Typical usage:
synchronized(obj) {
// do something
while(some condition is not met) {
obj.wait();
}
// do something other
}
Let's assume that you don't use wait(). Then, you have to implement busy loop polling the condition that you want, which is bad for performance.
synchronized(obj) {
// do something
while(some condition is not met) { // busy loop }
// do something other
}
Important note: Even though a thread is awaken by notify() or notifyAll() from other thread, the awaken thread does NOT guaranteed to immediately resume its execution. If there were other threads awaiting to execute a synchronized block on the same object, then the awaken thread should compete with the threads.

Related

Java Thread wait and notify methods

I'm learning for OCJP and now I'm at "Thread" chapter, I have some questions about wait and notify methods. I think I understand what's happening here but I just want to make sure that I'm on the right way.I wrote this code as an example:
package threads;
public class Main {
static Object lock = new Object();
public static void main(String[] args) {
new Main().new FirstThread().start();
new Main().new SecondThread().start();
}
class FirstThread extends Thread {
public void run() {
synchronized (lock) {
lock.notify();
System.out.println("I've entered in FirstThread");
}
}
}
class SecondThread extends Thread {
public void run() {
synchronized (lock) {
try {
lock.wait();
System.out.println("I'm in the second thread");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
In this example the console output is I've entered in FirstThread, because the first thread starts, the notify() method is called, then the second thread starts, the wait() method is called and the String "I'm in the second thread" is not printed.
The next scenario is that I reverse the positions of new Main().new FirstThread().start(); and new Main().new SecondThread().start(); the output is
I've entered in FirstThread
I'm in the second thread
because the second thread starts, the wait() method is called, then the first thread starts, the method notify() is called, the console prints I've entered in FirstThread, the wait is released and I'm in the second thread is printed in the console.
Is that happening because the computer is so fast and the threads run sequentially? Theoretically the second start() method can be called first in my opinion is it?.
And the last question I have, is why the lock Object must be static, because if I remove the static modifier the output is always I've entered in FirstThread?
I know that static fields are loaded in JVM when the class is loaded, but I can't understand the logic of lock Object.
The threads are started sequentially, and in theory thread 1 would execute before thread 2, although it's not guaranteed (pretty sure it'll be consistent in this simple case though, as there are no real or simulated aleatory delays).
This is why when thread 2 is started slightly before, it has a chance to wait on a lock that gets notified (by thread 1) subsequently, instead of waiting forever for a lock that's already been notified once (hence, no printing).
On the static lock Object: you're binding your [First/Second]Thread nested classes to instances of Main, so the lock has to be common to both if you want them to synchronize on the same lock.
If it was an instance object, your threads would access and synchronize on a different lock, as your new Main()... idiom would get two instances of Main and subsequently two instances of lock.
"Is that happening because the computer is so fast and the threads run
sequentially? Theoretically the second start() method can be called
first in my opinion is it?. "
Yes, you can introduce a sleep() with random time, for better (unit-) test, or demonstration purpose. (Of course, the final running code should not have that sleep)
And the last question I have, is why the lock Object must be static
Principally, it does not matter whether the lock is static or not, but you have to have the possibility to access it, and it must be the same lock object. (Not one object instance for each class). In your case it must be static, otherwise it would be two different objects instances.
This is wrong because it doesn't change any shared state that the other thread can test:
synchronized (lock) {
lock.notify();
System.out.println("I've entered in FirstThread");
}
And this is wrong because it does not test anything:
synchronized (lock) {
lock.wait();
System.out.println("I'm in the second thread");
}
The problem is, lock.notify() does not do anything at all if there is no thread sleeping in lock.wait(). In your program, it is possible for the FirstThread to call notify() before the SecondThread calls wait(). The wait() call will never return in that case because the notify() call will do nothing in that case.
There's a reason why they make you enter a mutex (i.e., a synchronized block) before you can call wait() or notify(). It's because you are supposed to use the mutex to protect the shared shared state for which the waiter is waiting.
"shared state" can be as simple as a single boolean:
boolean firstThreadRan = false;
The notifier (a.k.a., "producer") does this:
synchronized(lock) {
firstThreadRan = true;
lock.notify();
...
}
The waiter (a.k.a., "consumer") does this:
synchronized(lock) {
while (! firstThreadRan) {
lock.wait();
}
...
}
The while loop is not strictly necessary in this case, but it becomes very important when more than one consumer is competing for the same event. It's good practice to always use a loop.
See https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html for a tutorial that explains wait() and notify() in more detail.

What does it mean to have a synchronized block on a different monitor than 'this' instance?

I have the following piece of code. It has two objects, namely MultiThreadingTest, and the ThreadB object. When we say synchronized(b), what does it mean exactly? Can the 'main' thread get a lock on b before ThreadB finishes it's execution? I can't understand the significance of monitor object in the synchronized block.
package threads;
class MultiThreadingTest
{
public static void main(String[] args)
{
ThreadB b = new ThreadB();
b.setName("Thread B");
b.start();
synchronized(b)
{
System.out.println("Current thread : "+ Thread.currentThread().getName());
try
{
System.out.println("Waiting for b to complete...");
b.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("Total = "+b.total );
}
}
}
class ThreadB extends Thread
{
int total;
public void run()
{
synchronized(this)
{
System.out.println("Current thread : "+Thread.currentThread().getName());
for(int i=0;i<100;i++)
{
total = total + i;
}
notify();
}
}
}
Think of it like the child's game, whoever holds the [whatever object] gets to speak. Whoever holds the monitor object gets to execute in computing terms.
The monitor is the object you are locking upon, at any given time, only one thread accesses code protected by a synchronization block per monitor object. The object itself is arbitrary and doesn't hold much weight onto synchronization (though you have to watch out for reassigning variables as well as null references). Also, JB Nizet raises a good point here on synchronizing on a Thread object since many internal VM methods do that, you can cause bazaar, hard to detect bugs and deadlocks.
Two threads entering different synchronization blocks locking on different monitors will execute concurrently, analogous to two separate groups of people playing/enacting the "who ever holds to xxx gets to speak" game. Locking on this is just a convenient way to manifest a single lock synchronization without creating additional lock objects.
In your case, ThreadB b is the same object pointed to as this from within the ThreadB class meaning that only one thread can enter any of your defined synchronization blocks at once. The order is highly dependent on which thread ran first, the thread scheduler and even the underlying system.
The main reason for monitor objects is so that complex thread-safety mechanisms can be realized. Imagine a system where every synchronization block is single thread access (i.e. at any time, any thread enters a synchronization block will hold every other thread in the whole VM trying to enter a sync block) not only will this cause a massive performance slowdown, it just doesn't make sense. Why should two unrelated application modules lock on each other if they share no data and never interact?
The solution of course is to have one module use one (or several) monitor objects that are unrelated/unassociated with the other module, so both can execute concurrently independent of each other (assuming this is the desired behavior).
To further clarify, you could write:
class MultiThreadingTest{
public static void main(String[] args){
ThreadB b = new ThreadB();
b.setName("Thread B");
b.start();
synchronized(b.lock){
System.out.println("Current thread : "+ Thread.currentThread().getName());
try{
System.out.println("Waiting for b to complete...");
b.lock.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total = " + b.total );
}
}
}
class ThreadB extends Thread{
public final Object lock = new Object();
int total;
public void run(){
synchronized(lock){
System.out.println("Current thread : "+Thread.currentThread().getName());
for(int i = 0; i < 100; i++){
total = total + i;
}
lock.notify();
}
}
}
to exactly the same effect as the code you've used (even better, since it resolves the conflict with Thread.join() and other methods).
synchronized(this) means that you won't be able to enter this block of code if another thread is inside a block of code that is also synchronized on the object referenced by this.
synchronized(b) means that you won't be able to enter this block of code if another thread is inside a block of code that is also synchronized on the object referenced by b.
They thus do the exact same thing. The only difference is the object that is used to lock.
Note that waiting, synchronizing and notifying on an object of type Thread is a really really bad idea. It confuses things, and will lead to unwanted behavior because other methods (join() for example) also use the Thread as a monitor.
As per my understanding, no. The 'this' object within the run() method and the 'b' object in the main() method are the same.
Hence it would not be possible for the 'main' thread to acquire the lock until the thread completes execution.
Also the notify() within the run() method seems to be redundant in this case since its at the end of the method and the lock on the monitor would be relinquished any how.
PS: Do look around for similar questions that may already have been asked in the forum. They may help in providing additional understanding.

Two Synchronized blocks execution in Java

Why is it that two synchronized blocks can't be executed simultaneously by two different threads in Java.
EDIT
public class JavaApplication4 {
public static void main(String[] args) {
new JavaApplication4();
}
public JavaApplication4() {
Thread t1 = new Thread() {
#Override
public void run() {
if (Thread.currentThread().getName().equals("Thread-1")) {
test(Thread.currentThread().getName());
} else {
test1(Thread.currentThread().getName());
}
}
};
Thread t2 = new Thread(t1);
t2.start();
t1.start();
}
public synchronized void test(String msg) {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
System.out.println(msg);
}
}
public synchronized void test1(String msg) {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
System.out.println(msg + " from test1");
}
}
}
Your statement is false. Any number of synchronized blocks can execute in parallel as long as they don't contend for the same lock.
But if your question is about blocks contending for the same lock, then it is wrong to ask "why is it so" because that is the purpose of the whole concept. Programmers need a mutual exclusion mechanism and they get it from Java through synchronized.
Finally, you may be asking "Why would we ever need to mutually exclude code segments from executing in parallel". The answer to that would be that there are many data structures that only make sense when they are organized in a certain way and when a thread updates the structure, it necessarily does it part by part, so the structure is in a "broken" state while it's doing the update. If another thread were to come along at that point and try to read the structure, or even worse, update it on its own, the whole thing would fall apart.
EDIT
I saw your example and your comments and now it's obvious what is troubling you: the semantics of the synchronized modifier of a method. That means that the method will contend for a lock on this's monitor. All synchronized methods of the same object will contend for the same lock.
That is the whole concept of synchronization, if you are taking a lock on an object (or a class), none of the other threads can access any synchronized blocks.
Example
Class A{
public void method1()
{
synchronized(this)//Block 1 taking lock on Object
{
//do something
}
}
public void method2()
{
synchronized(this)//Block 2 taking lock on Object
{
//do something
}
}
}
If one thread of an Object enters any of the synchronized blocks, all others threads of the same object will have to wait for that thread to come out of the synchronized block to enter any of the synchronized blocks. If there are N number of such blocks, only one thread of the Object can access only one block at a time. Please note my emphasis on Threads of same Object. The concept will not apply if we are dealing with threads from different objects.
Let me also add that if you are taking a lock on class, the above concept will get expanded to any object of the class. So if instead of saying synchronized(this), I would have used synchronized(A.class), code will instruct JVM, that irrespective of the Object that thread belongs to, make it wait for other thread to finish the synchronized block execution.
Edit: Please understand that when you are taking a lock (by using synchronized keyword), you are not just taking lock on one block. You are taking lock on the object. That means you are telling JVM "hey, this thread is doing some critical work which might change the state of the object (or class), so don't let any other thread do any other critical work" . Critical work, here refers to all the code in synchronized blocks which take lock on that particular Object (or class), and not only in one synchronized block.
This is not absolutely true. If you are dealing with locks on different objects then multiple threads can execute those blocks.
synchronized(obj1){
//your code here
}
synchronized(obj2){
//your code here
}
In above case one thread can execute first and second can execute second block , the point is here threads are working with different locks.
Your statement is correct if threads are dealing with same lock.Every object is associated with only one lock in java if one thread has acquired the lock and executing then other thread has to wait until first thread release that lock.Lock can be acquired by synchronized block or method.
Two Threads can execute synchronized blocks simultaneously till the point they are not locking the same object.
In case the blocks are synchronized on different object... they can execute simultaneously.
synchronized(object1){
...
}
synchronized(object2){
...
}
EDIT:
Please reason the output for http://pastebin.com/tcJT009i
In your example when you are invoking synchronized methods the lock is acquired over the same object. Try creating two objects and see.

wait(n) is acting different each time I change the position of synchronized keyword

Refer below code
public void acquire(){
synchronized(a){
print("acquire()");
try{
//Thread.sleep(5000);
synchronized(this){
wait(5000);
}
print("I have awoken");
print("" + a);
}catch(Exception e){
e.printStackTrace();
}
}
print("Leaving acquire()");
}
public void modify(int n){
print("Entered in modfy");
synchronized(a){
try{
//Thread.sleep(5000);
synchronized(this){
wait(5000);
}
this.a=n;
print("new value" + a);
}catch(Exception e){
e.printStackTrace();
}
}
}
And
final SynchoTest ttObj = new SynchoTest();
Thread A = new Thread(new Runnable(){
public void run() {
ttObj.acquire();
}
},"A");
Thread B = new Thread(new Runnable(){
public void run() {
ttObj.modify(97);
}
},"B");
A.start();
B.start();
As i know about wait(n), it pauses a thread until notify()/notifyAll() get called or the specified time n is over.
But...
In above methods if I directly use wait(n) as I used Thread.sleep(n),
I get runtime exception.
If I synchronize both methods instead of surrounding wait(n) with
synchronized block then I am not getting any exception but both
threads get blocked forever.
But if I do like I attached ie wait(n) surrounding with synchronized
block, it is working fine.
Please tell me why? Also tell me why is it not behaving different on positioning synchronized block if I use sleep(n) instead of wait(n)?
My question is about various result of wait(n) on various position of synchronized keyword.
#Gray
notify() or notifyAll(), and wait() must be in a synchronized block
for the object you are waiting on
explained me why I was getting run time exception by positioning synchronized block on various position.
Now please explain me, why
public void method(){
synchronized(a){
synchronized(this){
wait(n);
}
}
}
is working fine. But
public synchronized void method(){
synchronized(a){
wait(n);
}
}
is blocking my thread forever.
wait(n) and sleep(n) are completely different methods for pausing the execution of code:
wait(n) is called on an Object instance and will pause execution until the notify()/notifyAll() method is called on that instance or until the timer (the parameter) expires.
sleep(n) is called on a Thread object and essentially stops the world as far as that thread is concerned.
What your question comes down to is:
Do you want your object to act as a mutex, waiting for another piece of code to complete before continuing on it's own? Then use wait(n) with a corresponding notify()/notifyAll() in the other code.
Do you want to stop execution of the whole thread for a given timeframe? Then use Thread.sleep(n).
Maybe your code is not working because you didn't call start() on your threads? After you instantiate your threads you need to:
A.start();
B.start();
Also, you cannot do something like the following pattern. You cannot synchronize on a and then change the object of a. Well you can do it but I doubt that's what you want. Basically the a would change and someone else locking on a would lock on another object so would be able to be in the synchronized block as well. Very bad pattern.
synchronized (a) {
...
// not good
this.a = n;
}
Also, if you are not joining with the threads, then the main thread is going to continue on and not wait for A and B to finish. The JVM will wait for them to finish however since they are not daemon threads. And you have no guarantee that A will be called before B so the modify and acquire can happen in any order.
The difference between sleep(5000) and wait(5000) is that the wait can also be awoken by a call to notify() or notifyAll(), and wait() must be in a synchronized block for the object you are waiting on. synchronized also causes a memory barrier to be crossed which synchronizes the storage between multiple threads. It is more expensive because of that but in your case since you look to be sharing this.a then the memory barrier is required.
It is nothing about positioning synchronized keyword. You are facing problem since you locking other object and try to wait for another. Well #Gray has already been explained it, so not repeating it.
For your another problem, regarding why both threads are getting blocked;
Thread A: locks this [A: Runnable]
Thread A: locks a [A: Runnable]
Thread B: waiting for this [A: Runnable, B:BLOCKED]
Thread A: release this (meets wait) [A: TIMED WAITING, B:BLOCKED]
Thread B: lock this [A: TIMED WAITING, B: Runnable]
Thread B: waiting for a which is already locked by thread A [A: TIMED WAITING, B:BLOCKED]
Thread A: waiting for this which is locked by thread B [A: BLOCKED, B:BLOCKED]

How to use java notify correctly in blocking queue implementation

I am trying to understand Java multi-threading constructs, and I am trying to write a simple implementation of blocking queue. Here is the code I have written:
class BlockingBoundedQueue<E>
{
#SuppressWarnings("unchecked")
BlockingBoundedQueue(int size)
{
fSize = size;
fArray = (E[]) new Object[size];
// fBlockingQueue = new ArrayBlockingQueue<E>(size);
}
BlockingQueue<E> fBlockingQueue;
public synchronized void put(E elem)
{
if(fCnt==fSize-1)
{
try
{
// Should I be waiting/locking on the shared array instead ? how ?
wait();
}
catch (InterruptedException e)
{
throw new RuntimeException("Waiting thread was interrupted during put with msg:",e);
}
}
else
{
fArray[fCnt++]=elem;
//How to notify threads waiting during take()
}
}
public synchronized E take()
{
if(fCnt==0)
{
try
{
// Should I be waiting/locking on the shared array instead ? how ?
wait();
}
catch (InterruptedException e)
{
throw new RuntimeException("Waiting thread was interrupted during take with msg:",e);
}
}
return fArray[fCnt--];
//How to notify threads waiting during put()
}
private int fCnt;
private int fSize;
private E[] fArray;
}
I want to notify threads waiting in Take() from put() and vice versa. Can someone please help me with the correct way of doing this.
I checked the java.utils implementation and it uses Condition and ReentrantLocks which are a little complex for me at this stage. I am okay of not being completely robust[but correct] for the sake of simplicity for now.
Thanks !
The short answer is, call notifyAll() where you have the comments //How to notify threads waiting during take()
Now for the more complete answer...
The reference to read is : Java Concurrency in Practice. The answer to your question is in there.
However, to briefly answer your question: in Java, threads synchronize by locking on the same object and using wait() and notify() to safely change state. The typical simplified flow is:
Thread A obtains a lock by entering a synchronized block on a lock object
Thread A checks some condition in a loop, if not "OK to go" call thread.wait(), which is a blocking call that "releases" the lock so other code synchronized on the same lock object can proceed
Thread B obtains the same lock and may do something that changes the condition thread A is waiting for. When it calls notifyAll(), thread A will wake up and recheck the condition and (may) proceed
Some things to remember about synchronization are:
it is about keeping state of objects consistent by making changes to state atomic. "Atomic" means the entire change (e.g. to multiple fields) is guaranteed to complete (no partial, and therefore inconsistent, changes)
it is cooperative - code synchronized on a given lock object has in common the state that is being changed and the conditions that allow that state change - you wait and notify about the same "subject". Each part of state should be guarded by its own lock object - usually a private field, e.g. private Object lock = new Object(); would be fine
methods that are synchronized use this as the lock object - doing this is easy but potentially expensive, because you are locking for every call, instead of just when you need to
static methods that are synchronized use the Class object as the lock object

Categories