How can two sync Methods (same Object) in Java run at the same time? - java

I was searching for a wait() and notify() example in the internet and found the following example.
In the following Code-Block, both getValue() and setValue Methods are synchronized. If i create two Threads and the first Thread gets the lock, isn't it true, that the second Thread will wait indefinitely, until the first Thread releases the Lock? So it is not possible, that getValue() and setValue() are run at the same time? If yes the wait() and notify() methods would be there for nothing.
tldr: How can getValue() and setValue() methods be called from different Threads at the same time?
public class Data {
private int value;
private boolean available = false;
public synchronized int getValue() {
while (!available) {
try {
wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
available = false;
notifyAll();
return value;
}
public synchronized void setValue(int value) {
while (available) {
try {
wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
this.value = value;
available = true;
notifyAll();
}
}

Quoting the documentation for Object.wait:
This method causes the current thread (call it T) to place itself in the wait set for this object and then to relinquish any and all synchronization claims on this object.
Essentially, wait is a special case that allows other threads to claim the lock until it is notified.

Related

java, synchronized in two separate methods?

I'm trying to create thread safe queue in java. I've come across this example:
class ProducerConsumer<T> {
private static final int BUFFER_MAX_SIZE = 42;
private List<T> buffer = new LinkedList<>();
synchronized void produce(T value) throws InterruptedException {
while (buffer.size() == BUFFER_MAX_SIZE) {
wait();
}
buffer.add(value);
notify();
}
synchronized T consume() throws InterruptedException {
while (buffer.size() == 0) {
wait();
}
T result = buffer.remove(0);
notify();
return result;
}
}
I'm new to java. In my understanding those two 'synchronized' keywords would prevent contention inside each method, but not when both methods are called simultaneously. E.g. thread P calls produce, locks method, thread C calls consume, locks other method, then one tries to extract element from list, another tries to insert element, thread exception arises.
My question: Is this example broken?
Or maybe I'm missing something and it's ok.
JLS, §17.1 is quite explicit about the mechanism:
...
A synchronized method (§8.4.3.6) automatically performs a lock action when it is invoked; its body is not executed until the lock action has successfully completed. If the method is an instance method, it locks the monitor associated with the instance for which it was invoked (that is, the object that will be known as this during execution of the body of the method). If the method is static, it locks the monitor associated with the Class object that represents the class in which the method is defined. If execution of the method's body is ever completed, either normally or abruptly, an unlock action is automatically performed on that same monitor.
...
Thus, it is guaranteed that at one point in time on one object at most one thread is executing either produce(...) or consume(). It is not possible that, at one point in time, one thread executes produce(...) on an object while another thread executes consume() on the same object.
The call to wait() in consume() releases the intrinsic lock and blocks execution. The call to notify() in produce(...) notifies one wait()ing thread (if any), so it can fight for the lock as soon as the lock is released by the current owner. Notice that a call to notify() does not release the intrinsic lock. It just wakes up a wait()ing thread. This can be made observable with the following code snippet:
class Ideone {
private static final Object lock = new Object();
public static void main(String[] args) {
printWithThreadNamePrefix("Start");
Thread waiter = new Thread(Ideone::waiter);
waiter.start();
// Give waiter some time to a) start and b) acquire the intrinsic lock
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
final Thread notifier = new Thread(Ideone::notifier);
notifier.start();
while (true) {
try {
waiter.join();
break;
} catch (InterruptedException e) {
}
}
printWithThreadNamePrefix("End");
}
private static void waiter() {
synchronized (lock) {
printWithThreadNamePrefix("Waiting...");
while (true) {
try {
lock.wait();
break;
} catch (InterruptedException e) {
}
}
printWithThreadNamePrefix("... done waiting");
}
}
private static void printWithThreadNamePrefix(String msg) {
System.out.println(String.format(
"%s: %s",
Thread.currentThread().getName(),
msg));
}
private static void notifier() {
synchronized (lock) {
printWithThreadNamePrefix("notifying");
lock.notify();
while (true) {
}
}
}
}
Ideone demo
The program will never terminate. Although thread two calls notify(), it then enters an endless loop, never actually releasing the intrinsic lock. Thus, one never has a chance to acquire the intrinsic lock, and the program "hangs" (it is neither a deadlock, nor a livelock, it simply cannot proceed).
The things I recommend to change are:
declare private List<T> buffer additionally as final
call notifyAll() instead of notify() in order to wake all waiting threads (they will still execute sequentially, for details see this question by Sergey Mikhanov and its answers)

Wait and Notify on same Thread

Is there anyway one single thread can wait and notify itself to "wake" up, or only
I got something like this but it isnt working and i get the illegalmonitorstateexception
public class test extends Thread{
private int n;
private int lim;
public test(int lim) {
n = 0;
this.lim=lim;
}
public synchronized void add() throws InterruptedException {
n++;
notify();
}
#Override
public void run() {
while(n!=lim){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//do something
}
}
Main
The confusion here appears to be with the idea of "notifying a thread". You don't (usually) call notify, notifyAll or wait of a Thread object. Invoke it any object that you are using as a lock. (A particular problem with Thread is that it is used as a lock for a particular purpose already (Thread.join).)
So you need some kind of lock object:
private final Object lock = new Object();
To wait on the object, you need to hold the lock and the condition should be checked in a while loop.
synchronized (lock) {
while (!some_condition) {
lock.wait();
}
...
}
To notify, hold the lock, notify (you might as well go for notifyAll, it'll be at least as good as notify and sometimes it may be necessary but not caught in testing) and change the condition.
synchronized (lock) {
lock.notifyAll();
some_condition = true;
}
Also, it good practice not to subclass Thread. Goes for other unnecessary subclassing too. Typically you would create a Runnable and pass it to the constructor.
IllegalMonitorStateException means you "don't own the monitor". To do that:
synchronized (this) {
wait()
}
What do you want to trigger the notification? As commented above, if a Thread is waiting, it can't take any action. Maybe you want to use a timeout?
Update:
To wait() until lim is reached, add this to the add() method:
if (n >= lim) {
notify();
}

Pause Thread after a method is called

Basically I want to pause my Thread after I called a method, before continuing to the other one. I can't loop, my method can only be ran once.
The idea behind this, is to be used in a game, where the methods will display messages, and each time a user presses a key, the next message sould be shown. I can't just go through a list, as the game takes input from the user. I looket at Thread.pause() and Thread.resume() but they woN't work either, and are deprecated.
My current code (Which isn't working):
private Thread thread;
private Thread managerThread;
private final Object lock = new Object();
private boolean shouldThreadRun = true;
private boolean storyRunning = true;
public Storyline() {
setUpThread();
}
private void setUpThread() {
managerThread = new Thread(() -> {
while(storyRunning) {
synchronized (lock) {
if(!shouldThreadRun) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Looping");
}
}
});
thread = new Thread(() -> {
synchronized (lock) {
pauseThread();
System.out.print("A");
pauseThread();
System.out.print("B");
}
});
managerThread.start();
thread.start();
}
public void pauseThread() {
shouldThreadRun = false;
}
public void resumeThread() {
shouldThreadRun = true;
}
Take a look at my edits and see if it is any similar to what you were trying to achieve. I'm using a scanner to simulate user input, just press enter on your keyboard to try it out.
By the way I hope this is just an exercise and not a real life situation. You should try to avoid this kind of low level management of multithreading in a real product, unless really necessary, in which case you should still use appropriate data structures meant for this. In a real application buttons will be linked to callbacks and you will set some onClick() method to execute the code you need, as soon as the button is pressed.
For what concerns concurrency, I strongly suggest you to take a look at these tutorials: Oracle-Concurrency
PS: notice that I'm completely ignoring interrupts, which is a bad practice, those exception should be handled the right way: I was just trying to achieve the desired result by keeping the code as simple as possible. Also, like someone else pointed out, you should handle spurious wakeups by just calling the wait inside a loop.
private Thread thread;
private Thread managerThread;
private final Object lock = new Object();
Scanner in;
public Storyline() {
setUpThread();
}
private void setUpThread() {
managerThread = new Thread(() -> {
while(true) {
in = new Scanner(System.in);
in.nextLine();
resumeThread();
}
});
thread = new Thread(() -> {
synchronized (lock) {
while(true){
System.out.print("A");
try {
lock.wait();
} catch (InterruptedException e) {}
System.out.print("B");
try {
lock.wait();
} catch (InterruptedException e) {}
}
}
});
managerThread.start();
thread.start();
}
public void resumeThread() {
synchronized(lock){
lock.notify();
}
}
The first rule of Object.wait, as described in the documentation, is that it must be called in a loop which depends on the condition which is the basis for the wait.
So, your wait needs to look like this:
synchronized (lock) {
while (!shouldThreadRun) {
lock.wait();
}
}
An interrupt is not something that happens by accident. A thread is only interrupted if another thread explicitly asks it to stop what it’s doing and exit cleanly.
Therefore, if you get an interrupt, the correct course of action is not to ignore it and print a stack trace. You need to exit cleanly.
The easiest way to do this is to simply enclose your entire while loop in a try/catch:
try {
while (storyRunning) {
synchronized (lock) {
while (!shouldThreadRun) {
lock.wait();
}
System.out.println("Looping");
}
}
} catch (InterruptedException e) {
System.out.println("Exiting, because someone asked me to stop.");
e.printStackTrace();
}
This way, your while-loop will automatically exit when interrupted.
Lastly, Object.wait is useless unless another thread calls Object.notify or Object.notifyAll on the very same object on which the waiting thread is synchronized. The wait method will (probably) never return unless the object gets a notify:
public void pauseThread() {
synchronized (lock) {
shouldThreadRun = false;
// Tell waiting thread that shouldThreadRun may have changed.
lock.notify();
}
}
public void resumeThread() {
synchronized (lock) {
shouldThreadRun = true;
// Tell waiting thread that shouldThreadRun may have changed.
lock.notify();
}
}
Notice that the synchronizing is inside the methods. If you keep your thread synchronized on lock all the time, the manager thread will never have a chance to run at all, because it’s trying to acquire a synchronization lock on the same object. (However, the opposite is not true; the manager thread can stay synchronized on lock all the time, because the wait() method will temporarily release the synchronization lock, allowing the other thread to proceed.)
If all code which accesses shouldThreadRun is inside synchronized blocks, you don’t need to (and should not) make shouldThreadRun volatile, since the synchronization already ensures multi-threaded consistency.

Blocking object property

I wrote a small class that blocks in a method if the value is null. For some reason, it is throwing a StackOverflowError, what I am doing wrong?
public class BlockingObjectProperty<T> extends SimpleObjectProperty<T> {
public T get() {
if (super.get() == null) {
addListener(((observableValue, t, t1) -> {
synchronized (this) {
notifyAll();
}
}));
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}
return super.get();
}
}
Here is my test code:
BlockingObjectProperty<String> blockingObjectProperty = new BlockingObjectProperty<String>();
new Thread(){
public void run(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
blockingObjectProperty.set("hello world");
}
}.start();
System.out.println(blockingObjectProperty.get());
And here is a snippet of the exception:
Exception in thread "main" java.lang.StackOverflowError
at com.sun.javafx.binding.ExpressionHelper$SingleChange.<init>(ExpressionHelper.java:144)
at com.sun.javafx.binding.ExpressionHelper.addListener(ExpressionHelper.java:69)
at javafx.beans.property.ObjectPropertyBase.addListener(ObjectPropertyBase.java:87)
at com.neonorb.commons.property.BlockingObjectProperty.get(BlockingObjectProperty.java:8)
at javafx.beans.binding.ObjectExpression.getValue(ObjectExpression.java:50)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.<init>(ExpressionHelper.java:152)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.<init>(ExpressionHelper.java:144)
at com.sun.javafx.binding.ExpressionHelper.addListener(ExpressionHelper.java:69)
at javafx.beans.property.ObjectPropertyBase.addListener(ObjectPropertyBase.java:87)
at com.neonorb.commons.property.BlockingObjectProperty.get(BlockingObjectProperty.java:8)
at javafx.beans.binding.ObjectExpression.getValue(ObjectExpression.java:50)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.<init>(ExpressionHelper.java:152)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.<init>(ExpressionHelper.java:144)
at com.sun.javafx.binding.ExpressionHelper.addListener(ExpressionHelper.java:69)
at javafx.beans.property.ObjectPropertyBase.addListener(ObjectPropertyBase.java:87)
at com.neonorb.commons.property.BlockingObjectProperty.get(BlockingObjectProperty.java:8)
When you call addListener JavaFX asks the property for its current value (in ExpressionHelper.java:152), calling getValue() again. Then - since the value is still null - you add another listener and so on ad infinitum.
If you want to wait for some variable to become non-null:
private final Object myVarLock = new Object();
private MyType myVar;
MyType get_myVar() {
synchronized(myVarLock) {
while (myVar == NULL) {
myVarLock.wait();
}
return myVar;
}
}
And to set the variable:
void set_myVar(myType newValue) {
synchronized(myVarLock) {
myVar = newValue;
myVarLock.notifyAll();
}
}
NOTES
The getter waits in a loop. This is necessary for strict correctness because the Java Langauge Spec allows wait() to return even when it has not been notified. (a.k.a., spurious wakeup).
Even if spurious wakeups don't happen in your JVM or in your application, it still is smart to always use a loop. The loop is essential in any algorithm where multiple consumer threads compete with one another to receive events. The loop doesn't cost any more than an if, so you might as well just be in the habit of always using the loop.
The test of myVar and the assignment of myVar both are inside the synchronized blocks. This is important. If they weren't both synchronized then here is what could happen:
Thread A enters the getter, tests myVar and finds that it equals NULL.
Thread B enters the setter, sets myVar non-null, calls myVarLock.notifyAll(), returns. The notification is lost because no other thread was waiting for it.
Thread A calls myVarLock.wait() and waits forever, for an event that is never going to happen again.

Java notify() gets called before wait()

Isn't it possible that notify() in another thread gets called before the wait() in one thread?
It's happening with me.
A client requests a value from a target and waits on a result variable RV.
In case the target is the client itself, I update RV with the correct result and call notify() on RV in another thread.
class EMU {
ResultVar RV;
Address my_address;
ResultVar findValue(String key) {
String tgt = findTarget(key);
sendRequest(tgt, key);
synchronized(RV) {
RV.wait();
}
return RV;
}
Runnable Server = new Runnable() {
public void run() {
//code to receive connections. Assume object of type Request is read from the stream.
Request r = (Request) ois.readObject();
if(r.requesterAddr.compareTo(my_address) == 0) {
String val = findVal(key);
RV.putVal(val);
synchronized(RV){
RV.notify();
}
}
}
};
}
The problem is that before the requester has completed all the "networking" (sendReqest in the above example) with itself, the result is updated in the result variable. When the requester thread now calls wait(), the program doesn't continue, since notify has already been called.
How can we prevent it?
You check some flag before waiting (in a loop), see the tutorial: http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
Nothing stops you calling notify on an object that's not being waited by another thread.
It sounds like what you want is a wait only if some condition holds. For example:
synchronized (results) {
while (!results.hasResults()) {
// no results yet; wait for them
try {
results.wait();
} catch (InterruptedException ie) { /* ignore */ }
}
}
I'd strongly recommend not re-inventing the wheel.
Java's Future interface is designed for results that may only arrive later, and the FutureTask class implements this interface.
Have the first thread obtain access to the Future and get the second thread to run the FutureTask, and all of this stuff gets handled for you. You also get timeout support for free.
Use some condition before going to wait() and make sure that condition is thread safe :)
class EMU{
ResultVar RV;
Address my_address;
volatile boolean condition = true;
ResultVar findValue(String key){
String tgt = findTarget(key);
sendRequest(tgt, key);
synchronized(RV){
while(condition == true)
{
RV.wait();
}
}
return RV;
}
Runnable Server = new Runnable(){
public void run(){
//code to receive connections. Assume object of type Request is read from the stream.
Request r = (Request) ois.readObject();
if(r.requesterAddr.compareTo(my_address) == 0){
String val = findVal(key);
RV.putVal(val);
synchronized(RV){
condition = false;
RV.notify();
}
}
}
};
Let me first break down the code to a minimum reproducable:
public static void main(String[] args) throws Exception {
Object RV = new Object();
new Thread() {
#Override
public void run() {
synchronized (RV) {
RV.notify();
}
}
}.start();
Thread.sleep(1_000);
synchronized (RV) {
RV.wait();
}
}
This method will theoretically never end and the program will never quit. It shall be a dispute if this is a deadlock.
My solution is to create a second lock:
public static void main(String[] args) throws Exception {
Object RV = new Object();
Object lock = new Object();
new Thread() {
#Override
public void run() {
synchronized (lock) {
lock.wait();
}
synchronized (RV) {
RV.notify();
}
}
}.start();
Thread.sleep(1_000);
synchronized (RV) {
synchronized (lock) {
lock.notify();
}
RV.wait();
}
}
Lets inspect what the threads are doing while the main-thread is waiting one second:
The custom Thread will first join the synchronized(lock) block.
Then the lock will causes the custom Thread to wait.
After 1 second the main-thread is joining a RV-synchronization.
The lock gets notified and causes the custom Thread to continue the work.
The custom thread leaves the synchronized(lock) block.
The main thread will RV-wait-lock.
The custom thread notifies the RV-lock to continue.
The program ends.

Categories