Difference between synchronized(this) and few synchronized methods of class - java

In Programming Interviews Exposed book (Wrox publications), code for Producer consumer problem uses 'synchronized' keyword for each of produce() and consume() methods inside a class called IntBuffer. Is this different than using synchronized(this) inside each of those methods ? The book says, "When a thread is busy waiting in produce(), no thread can enter consume() because methods are synchronized." I don't feel that makes sense for the code in the book because, when a thread is busy waiting in produce(), no thread can enter produce(). However other thread can enter consume() which shatters the idea of mutual exclusion. The methods produce and consume should both entirely be synchronized right ?
Code in the book:
public class IntBuffer
{
private int index;
private int[] buffer = new int[8];
// Function called by producer thread
public synchronized void produce(int num) {
while(index == buffer.length - 1) {
try { wait();}
catch(InterruptedException ex) {}
}
buffer[index++] = num;
notifyAll();
}
// Function called by consumer thread
public synchronized int consume() {
while(index == 0) {
try { wait();}
catch(InterruptedException ex) {}
}
int ret = buffer[--index];
notifyAll();
return ret;
}
}

No, they are the same.
private synchronized void foo() {}
private void foo2() {
synchronized(this){
}
}
They will do the exact same as both monitor the instance which they are called from.
A good tutorial can be found in the blog of Jakob Jenkov
http://tutorials.jenkov.com/java-concurrency/synchronized.html#java-synchronized-example
Happy coding!

Using synchronized(this) requires the calling thread to take the same lock as when it calls an instance method using the synchronized modifier on the method. There are some differences in what bytecode is generated but that's a pretty low-level distinction.
The purpose of the synchronized keyword is to protect shared state from concurrent access. The produce and consume methods use the same internal state so it's reasonable that they are both protected by the same lock.
The posted code looks well-done, my only nitpick is i would let the methods throw InterruptedException instead of catching it. Both the produce and consume methods require the calling thread to acquire the lock on the instance that the method is being called on.

Q: Is this different than using synchronized(this) inside each of those methods ?
A : No, it is not different, by using block (synchronize(this) you can synchronize just part of your code, not the whole method.
For example :
public void m1(){
// some code
synchronized(this){
// thread-safe code
}

Is this different than using synchronized(this) inside each of those methods?
No.
The book says, "When a thread is busy waiting in produce(), no thread can enter consume() because methods are synchronized." I don't feel that makes sense for the code in the book because, when a thread is busy waiting in produce(), no thread can enter produce(). However other thread can enter consume() which shatters the idea of mutual exclusion.
That's not correct. Both methods are synchronized on the same object, so only one thread can be in either method, unless wait() is called, which it is, which releases the lock.
The methods produce and consume should both entirely be synchronized right?
Yes, and you said they are. Unclear what you are asking here.

Related

How to create user defined SettableFuture in java [duplicate]

I am using multi-threading in java for my program.
I have run thread successfully but when I am using Thread.wait(), it is throwing java.lang.IllegalMonitorStateException.
How can I make a thread wait until it will be notified?
You need to be in a synchronized block in order for Object.wait() to work.
Also, I recommend looking at the concurrency packages instead of the old school threading packages. They are safer and way easier to work with.
EDIT
I assumed you meant Object.wait() as your exception is what happens when you try to gain access without holding the objects lock.
wait is defined in Object, and not it Thread. The monitor on Thread is a little unpredictable.
Although all Java objects have monitors, it is generally better to have a dedicated lock:
private final Object lock = new Object();
You can get slightly easier to read diagnostics, at a small memory cost (about 2K per process) by using a named class:
private static final class Lock { }
private final Object lock = new Lock();
In order to wait or notify/notifyAll an object, you need to be holding the lock with the synchronized statement. Also, you will need a while loop to check for the wakeup condition (find a good text on threading to explain why).
synchronized (lock) {
while (!isWakeupNeeded()) {
lock.wait();
}
}
To notify:
synchronized (lock) {
makeWakeupNeeded();
lock.notifyAll();
}
It is well worth getting to understand both Java language and java.util.concurrent.locks locks (and java.util.concurrent.atomic) when getting into multithreading. But use java.util.concurrent data structures whenever you can.
I know this thread is almost 2 years old but still need to close this since I also came to this Q/A session with same issue...
Please read this definition of illegalMonitorException again and again...
IllegalMonitorException is thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
This line again and again says, IllegalMonitorException comes when one of the 2 situation occurs....
1> wait on an object's monitor without owning the specified monitor.
2> notify other threads waiting on an object's monitor without owning the specified monitor.
Some might have got their answers... who all doesn't, then please check 2 statements....
synchronized (object)
object.wait()
If both object are same... then no illegalMonitorException can come.
Now again read the IllegalMonitorException definition and you wont forget it again...
Based on your comments it sounds like you are doing something like this:
Thread thread = new Thread(new Runnable(){
public void run() { // do stuff }});
thread.start();
...
thread.wait();
There are three problems.
As others have said, obj.wait() can only be called if the current thread holds the primitive lock / mutex for obj. If the current thread does not hold the lock, you get the exception you are seeing.
The thread.wait() call does not do what you seem to be expecting it to do. Specifically, thread.wait() does not cause the nominated thread to wait. Rather it causes the current thread to wait until some other thread calls thread.notify() or thread.notifyAll().
There is actually no safe way to force a Thread instance to pause if it doesn't want to. (The nearest that Java has to this is the deprecated Thread.suspend() method, but that method is inherently unsafe, as is explained in the Javadoc.)
If you want the newly started Thread to pause, the best way to do it is to create a CountdownLatch instance and have the thread call await() on the latch to pause itself. The main thread would then call countDown() on the latch to let the paused thread continue.
Orthogonal to the previous points, using a Thread object as a lock / mutex may cause problems. For example, the javadoc for Thread::join says:
This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
Since you haven't posted code, we're kind of working in the dark. What are the details of the exception?
Are you calling Thread.wait() from within the thread, or outside it?
I ask this because according to the javadoc for IllegalMonitorStateException, it is:
Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
To clarify this answer, this call to wait on a thread also throws IllegalMonitorStateException, despite being called from within a synchronized block:
private static final class Lock { }
private final Object lock = new Lock();
#Test
public void testRun() {
ThreadWorker worker = new ThreadWorker();
System.out.println ("Starting worker");
worker.start();
System.out.println ("Worker started - telling it to wait");
try {
synchronized (lock) {
worker.wait();
}
} catch (InterruptedException e1) {
String msg = "InterruptedException: [" + e1.getLocalizedMessage() + "]";
System.out.println (msg);
e1.printStackTrace();
System.out.flush();
}
System.out.println ("Worker done waiting, we're now waiting for it by joining");
try {
worker.join();
} catch (InterruptedException ex) { }
}
In order to deal with the IllegalMonitorStateException, you must verify that all invocations of the wait, notify and notifyAll methods are taking place only when the calling thread owns the appropriate monitor. The most simple solution is to enclose these calls inside synchronized blocks. The synchronization object that shall be invoked in the synchronized statement is the one whose monitor must be acquired.
Here is the simple example for to understand the concept of monitor
public class SimpleMonitorState {
public static void main(String args[]) throws InterruptedException {
SimpleMonitorState t = new SimpleMonitorState();
SimpleRunnable m = new SimpleRunnable(t);
Thread t1 = new Thread(m);
t1.start();
t.call();
}
public void call() throws InterruptedException {
synchronized (this) {
wait();
System.out.println("Single by Threads ");
}
}
}
class SimpleRunnable implements Runnable {
SimpleMonitorState t;
SimpleRunnable(SimpleMonitorState t) {
this.t = t;
}
#Override
public void run() {
try {
// Sleep
Thread.sleep(10000);
synchronized (this.t) {
this.t.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Thread.wait() call make sense inside a code that synchronizes on Thread.class object. I don't think it's what you meant.
You ask
How can I make a thread wait until it will be notified?
You can make only your current thread wait. Any other thread can be only gently asked to wait, if it agree.
If you want to wait for some condition, you need a lock object - Thread.class object is a very bad choice - it is a singleton AFAIK so synchronizing on it (except for Thread static methods) is dangerous.
Details for synchronization and waiting are already explained by Tom Hawtin.
java.lang.IllegalMonitorStateException means you are trying to wait on object on which you are not synchronized - it's illegal to do so.
Not sure if this will help somebody else out or not but this was the key part to fix my problem in user "Tom Hawtin - tacklin"'s answer above:
synchronized (lock) {
makeWakeupNeeded();
lock.notifyAll();
}
Just the fact that the "lock" is passed as an argument in synchronized() and it is also used in "lock".notifyAll();
Once I made it in those 2 places I got it working
I received a IllegalMonitorStateException while trying to wake up a thread in / from a different class / thread. In java 8 you can use the lock features of the new Concurrency API instead of synchronized functions.
I was already storing objects for asynchronous websocket transactions in a WeakHashMap. The solution in my case was to also store a lock object in a ConcurrentHashMap for synchronous replies. Note the condition.await (not .wait).
To handle the multi threading I used a Executors.newCachedThreadPool() to create a thread pool.
Those who are using Java 7.0 or below version can refer the code which I used here and it works.
public class WaitTest {
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
public void waitHere(long waitTime) {
System.out.println("wait started...");
lock.lock();
try {
condition.await(waitTime, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lock.unlock();
System.out.println("wait ends here...");
}
public static void main(String[] args) {
//Your Code
new WaitTest().waitHere(10);
//Your Code
}
}
For calling wait()/notify() on object, it needs to be inside synchronized block. So first you have to take lock on object then would be possible to call these function.
synchronized(obj)
{
obj.wait()
}
For detailed explanation:
https://dzone.com/articles/multithreading-java-and-interviewspart-2
wait(), notify() and notifyAll() methods should only be called in syncronized contexts.
For example, in a syncronized block:
syncronized (obj) {
obj.wait();
}
Or, in a syncronized method:
syncronized static void myMethod() {
wait();
}

Synchronizer Confusion

class MutableInteger {
private int value;
public synchronized void increment() {
value++;
}
public synchronized int getValue() {
return value;
}
public void nonSync(){
}
}
I am trying to understand how the synchronization keyword works.
I have a class with methods that are sychronized, this means that on that specific instance of the object, only one thread can call that method at a time? This only pertains to that method though? So if a thread A was calling incriment, thread B would have to wait until thread A was done executing the method? But this is only a method by method basis?
however, if I did
synchronized(this) {
//code
}
that would lock the entire instance of the object?
Does that make sense.. I get in essence what this is supposed to be doing, just trying to fill the gaps
You are right, synchronized methods are locking the instance itself.
So writing the followings:
synchronized myMethod() {
//code
}
Is essentially the same behavior as if you have written:
myMethod() {
synchronized(this) {
//code
}
}
Note, that this is simply an Object and is used as the lock as any other object would be used - the lock can be owned by only one thread at a time, the others must wait for it to enter a synchronized block using the same object. Since methods having the synchronized keyword behave such a way, they share the lock being the instance itself.
So, if you have an increment() and decrement() method both marked synchronized, then only either of the two can be used and by one thread at a time.
Meanwhile, other methods without the synchronized keyword remain completely unaffected and will function the same, whether there are synchronized methods around them or not.

Is it possible that 2 synchronized methods of an object are accessible by 2 threads at the same time?

This question was asked to me in an interview. Before I had told him this,
Once a thread enters any synchronized method on an instance, no other
thread can enter any other synchronized method on the same instance.
Consider the snippet:
Q1:
public class Q1 {
int n;
boolean valueSet = false;
synchronized int get() {
while (!valueSet)
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
System.out.println("Got: " + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n) {
while (valueSet)
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.n = n;
valueSet = true;
System.out.println("Put: " + n);
notify();
}
}
Producer1:
public class Producer1 implements Runnable {
Q1 q;
Producer1(Q1 q) {
this.q = q;
new Thread(this, "Producer").start();
}
#Override
public void run() {
int i = 0;
while (true) {
q.put(i++);
}
}
}
Consumer1
public class Consumer1 implements Runnable {
Q1 q;
Consumer1(Q1 q) {
this.q = q;
new Thread(this, "Consumer").start();
}
#Override
public void run() {
while (true) {
q.get();
}
}
}
PC1:
public class PC1 {
public static void main(String args[]) {
Q1 q = new Q1();
new Producer1(q);
new Consumer1(q);
System.out.println("Press Control-C to stop.");
}
}
So, he asked as soon as you have created this thread new Producer1(q), then according to you, the synchronized int get() method must have been locked by the same thread, i.e, by new Producer1(q) when it accessed synchronized int put(). I said yes.
But I checked in eclipse, get is callable by new Consumer1(q). The program works perfect.
Where am I going wrong?
O/P:
The call to wait() will release the monitor for the time waiting.
That's what is documented for Object.wait():
The current thread must own this object's monitor. The thread
releases ownership of this monitor and waits until another thread
notifies threads waiting on this object's monitor to wake up
either through a call to the notify method or the
notifyAll method. The thread then waits until it can
re-obtain ownership of the monitor and resumes execution.
Once a thread enters any synchronized method on an instance, no other
thread can enter any other synchronized method on the same instance.
What you forgot to add here is "except if the lock is released".
...and it is the case in your example, when calling wait.
The documentation specify :
The thread releases ownership of this monitor and waits until another
thread notifies threads waiting on this object's monitor to wake up
either through a call to the notify method or the notifyAll method.
Since the lock is released, you step in the other method (and the condition is true because the boolean was modified). Once in the other method, you release the lock again, then call notify and you wake up the old thread which terminates (re-modify boolean to pass the condition in other method, and notify). That way you step between both methods ad-infinitum.
wait() and notify() is acts as a signal between threads, to control the threads to do or to not do the stuff.
The program works perfect because here 2 threads (Producer, Consumer) which fight for the one lock (monitor). When Consumer aquires the lock (Q1 object) then Producer is waiting for the lock. When Consumer finishes his work it release the lock. Consumer releases the lock also when wait() method has been called, because wait() sets thread to Waiting state with lock release. It's time for Producer to aquire the lock and does his work. When Producer thread notify() calls then Consumer continue his work (when aquired the lock). The same is right for Producer.
Resume: Q1 object is a lock for all threads. If it aquired someone then others are blocked and the answer is - it not possible to get an access at the same time to the get(), put() methods more then 2 threads.
I think that the question is ambiguous. (E.g., what does "accessible" mean?)
IMO, a good interview question should not have a right answer and a wrong answer. A good interview question should be a conversation starter, that gives you an opportunity to show how much you know about the subject.
When I am asking the interview questions, I like a candidate who can see through the question, and get down to the underlying mechanism. E.g.,
What the JLS guarantees is that no two threads can be _synchronized_
on the same instance at the same time...
Then we could explore questions like, how could two threads enter the same synchronized method at the same time? (e.g., synchronized on different instances), how could two threads be in the same synchronized method for the same instance at the same time (one of them could be in a wait() call), ...
A thread can not access a synchronized block of code unless it has aquired a lock on the object that guards the block. In your case, the synchronized keyword uses the lock of the object in which it has been declared. So as long as a thread is executing get(), no other thread can execute the put().
If you apply this, when put() sets the value, it notifies consumer which accepts the value. The code should work even after you have removed the wait() and notify() calls from both get and put methods

notify() in synchronized block

I have found the blow code in a project. But i cant understand why the only notify() method is in synchronized block .
synchronized(this){
notify();
}
Is this code logical and if so what is the real purpose ?
You're supposed to call notify only from a thread that owns the object's monitor. From the documentation:
This method should only be called by a thread that is the owner of this object's monitor. A thread becomes the owner of the object's monitor in one of three ways:
By executing a synchronized instance method of that object.
By executing the body of a synchronized statement that synchronizes on the object.
For objects of type Class, by executing a synchronized static method of that class.
(My emphasis)
notify( ) wakes up the first thread that called wait( ) on the same object.
class ThreadB extends Thread{
int total;
#Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
notify();
}
}
Like above example, we use notify to send information message(hey i finished my work, wake up !) to other thread which is waiting. So at your question, it is not meaningful
To understand why it makes sense, consider that there have to be other blocks synchronized on the same object, that will be waken up by this block.
Take a look at this:
http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
This is not necessarily incorrect but definitely a bad sign. Somewhere else in that code, there will be an unconditional wait. E.g.:
synchronized(this) {
wait();
}
this might be working correctly now. But, if notify is ever executed before wait this will result in a deadlock.
Usually you want to wait on some condition:
synchronized(this) {
while(!this.flag) {
this.wait();
}
}
and use notify like this:
synchronized(this) {
this.flag = true;
this.notify();
}
This will never deadlock on it's own and it's clear what we are waiting for.

what does it mean when we say synchronized(instance field)..?

Attached the code..
what does this mean, synchronized(m)..?? why we should use that..??
What's the difference between synchronized(this) & synchronized(m)..??
class Waiter implements Runnable {
Message m;
public Waiter(Message m) {
this.m = m;
}
#Override
public void run() {
String name = Thread.currentThread().getName();
synchronized (m) {
try {
System.out.println("Waiting to get notified at time " +System.currentTimeMillis());
m.wait();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("Waiter thread notified at time "+System.currentTimeMillis());
System.out.println("Message processed ");
}
}
}
The difference between synchronized(this) and synchronized(m) is that by synchronizing on this, you synchronize on the entire instance. So, as you would expect, no body would be able to synchronize on this while you hold the lock.
public synchronized void foo() {
// Handle shared resource
}
is similar to
public void foo() {
synchronize(this) {
// Handle shared resource
}
}
By using objects, such as m, you get a more fine grained control over what you want to synchronize and when. But remember that if someone uses foo(), as shown above, it will not stop access to methods that are not synchronized on this:
public void anotherLock() {
synchronized(m) {
// Should handle another shared resource
// otherwise you might get unexpected results
}
}
While a thread is using foo(), another thread can access anotherLock().
The java keyword synchronized is used to synchronize different threads by one instance, acting as a mutual exclusive semaphore. Hence, the argument passed to synchronized is the instance which can be owned by one thread exclusively. It is up to you, the programmer, on which instance you like to synchronize your threads.
But it is a good idea to use the resource, which is under racing conditions, or the owning instance of that resource. The later you start a synchronized block and the earlier you leave it, the better your application will scale.
synchronized is used for thread safety. In your case it is used for implementing observer pattern. you want to wait for something to happen on Message object and then only process it so someone will notify on Message object m for which you are waiting (m.wait()).
When you wait on some object you need to take lock on that object for which you always need to put the wait() statement in a synchronized block on wait object. That is why you are using synchronized(m).
You can not replace it with synchronized(this) as you are calling wait() on object m so synchronized should be on m only.
Somewhere in your application you must be calling m.notify() or m.notifyAll() which will resume your wait() on m.

Categories

Resources