Wait and Notify on same Thread - java

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();
}

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)

(Java) Thread safety using Object wait() and notify()

I was looking for a way to make one thread wait/sleep until another thread signalled that something was ready. The waiting thread should wake up, process the data that was made available, then go back to sleep until the other thread signalled again.
The simplest method I could find was Object.wait() and Object.notify(), which behaved like a semaphore initialised to value 0. However, without the synchronized statements around notify/wait, Java always threw IllegalMonitorStateException when the thread was not the monitor owner. So I simply put them around the code like shown below.
THREAD 1: running infinite loop
public class Main {
private Handler handler; // only one instance (singleton pattern)
public void listen() {
while (true) {
try {
synchronized (handler) {
handler.wait();
int value = handler.getSize();
// do something
}
} catch (InterruptedException e) {
// ...
}
}
}
}
THREAD 2: Some other class calls removeItem
public class Handler {
// SINGLETON PATTERN - ONLY ONE INSTANCE
private ArrayList<Integer> sharedList;
private Handler() {
sharedList = new ArrayList<>();
}
public void addItem(Integer i) {
synchronized (sharedList) {
// add to list
}
}
public void removeItem(int i) {
synchronized (sharedList) {
// remove item
// notify that something is removed
synchronized (this) {
this.notify(); // this == handler
}
}
}
public int getSize() {
synchronized (sharedList) {
return sharedList.size();
}
}
}
It seems to work perfectly fine but not sure if there is a hidden bug.
My question is: Is this safe? Does wait release the instance lock for handler/this so notify can acquire the lock?
Synchronized blocks are safe. The statement synchronized(obj) acquires the lock of the argument obj, so you can call wait and notify on it. They both require that the current thread holds the lock on the object.
You have to be careful about the double-locking you have in removeItem where you lock two objects. If you ever need this, you have to make sure that you always lock them in the same order, otherwise, you may create a deadlock.

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.

Is this semaphore implementation faulty?

In my current assignment, we are to use a Semaphore to synchronize access to critical sections. However, the provided implementation has me questioning whether it is properly implemented or not. I'd like someone to confirm my worries.
public class Semaphore {
private int iValue;
public Semaphore(int piValue) {
this.iValue = piValue;
}
public Semaphore() {
this(0);
}
public synchronized boolean isLocked() {
return (this.iValue <= 0);
}
public synchronized void P() {
try {
while(this.iValue <= 0) {
wait();
}
this.iValue--;
} catch(InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void V() {
++this.iValue;
notifyAll();
}
}
I believe that there is a possibility for deadlock in this code:
Thread A calls P() and iValue is decremented to 0.
Thread B calls P() before thread A can call V(). The value of iValue is 0, so it enters the while loop.
Thread A now tries to call V(), but cannot because thread B holds the lock. Therefore, there is a deadlock.
Is my conclusion correct?
No.
When you wait the lock is released (you get it back when the wait is over).
Javadoc for 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.

Wait/Notify dead lock

I have a queue with some blocking mechanism in "Add" and "Get" methods, where first thread adds data and second thread gets data.
public synchronized MyObj getData() {
synchronized (myLock) {
synchronized (this) {
if (isEmpty()) {
wait(0);
}
}
return getData();
}
}
public synchronized void addData(MyObj data) {
if (!isFull()) {
putData(data);
synchronized (this) {
notify();
}
}
}
In the code above, if first thread tries to get data and queue is empty i put in wait via wait(0) until other thread add data to queue an release from waiting via notify().
Now I want to add another "lock" when queue is full and some one tries to add more data to it:
public synchronized MyObj getData() {
synchronized (myLock) {
synchronized (this) {
if (isEmpty()) {
wait(0);
}
}
synchronized (this) {
notify();
}
return getData();
}
}
public synchronized void addData(MyObj data) {
synchronized (myLock) {
synchronized (this) {
if (isFull()) {
wait(0);
}
}
}
synchronized (this) {
notify();
}
PutData(data);
}
The result is not what I expect , I guess that i get a dead lock cause process is stuck.
UPDATE
This is how I get data:
queueSize--;
startPointer = (startPointer + 1) % mqueueSize;
data = (String) queue[startPointer];
this is how i add data
queueSize++;
endPointer = (endPointer + 1) % mqueueSize;
queue[endPointer] = data;
public synchronized boolean isEmpty() {
return queueSize== 0;
}
public synchronized boolean isFull() {
return queueSize== mqueueSize;
}
Why do you have three synchronized statements? The wait(0) only releases the lock on this, so just keep that one and dump the synchronized from the method and the synchronized(myLock).
Whenever you call wait on some object (in this case you are calling on this), the lock on that object is automatically released to allow the other thread to proceed. But you are never calling wait on myLock (and nor should you, because you are calling on this already). That part is redundant and causes the deadlock.
Consider this scenario: the thread that is supposed to add takes the lock on myLock but finds the queue full, so it waits. This wait does not release the lock on myLock. The other thread wants to take data but cannot enter the synchronized block because the first thread did not release the lock on myLock.
Conclusion: remove the synchronized(myLock) blocks.
Why you don't take a look in java.util.BlockingQueue. Probably it will be useful in your situation.
Particularly take a look at java.util.LinkedBlockingQueue, where if you specify the queue's capacity in the constructor, then the queue will block.
Remove the synchronized keyword from your method signatures, as that implies you hold the this monitor for the whole method call -- the synchronized(this) blocks are simply redundant.
EDIT:
...Then call wait and notify on myLock rather than this. And forget completely about synchronizing on this. This is because while waiting (on this in your current code), you're not releasing the myLock lock, so the other thread is not able to get to notify().
Replace if with while. It won't hurt to double check, if the collection really become not empty/not full.
You don't really need two locks. Single lock will work almost as well and should be much simpler.
public synchronized T get()
{
while(isEmpty())
wait(0);
notifyAll();
return super.get();
}
public synchronized put(T t)
{
while(isFull())
wait(0);
super.put(t);
notifyAll();
}
All threads will wake up when something changes. But if they can't do their work, they will wait for next notify.
As already mentioned, your code has too many synchronized annotations. Also, the condition to wait on is checked in an if conditional, but it should ideally be checked in a while loop to avoid spurious wakeups. Here is the outline of the code that fixes these.
// _isEmpty and _getData are private unsynchronized methods
public MyData get() throws InterruptedException {
// wait and notify should be called from a block
// synchronized on the same lock object (here myLock)
synchronized (myLock) {
// the condition should be tested in a while loop
// to avoid issues with spurious wakeups
while (_isEmpty()) {
// releases the lock and wait for a notify to be called
myLock.wait();
}
// when control reaches here, we know for sure that
// the queue is not empty
MyData data = _getData();
// try to wake up all waiting threads - maybe some thread
// is waiting for the queue not to be full
myLock.notifyAll();
}
}
// _isFull and _putData are private unsynchronized methods
public void put(MyData obj) throws InterruptedException {
synchronized (myLock) {
while (_isFull()) {
myLock.wait();
}
_putData(obj);
myLock.notifyAll();
}
}

Categories