Hello I'm having problems understand this code that is presented here, this code shows an example of how to correctly implement wait() and notify() into a thread.
Here's the code:
class Q {
int n;
boolean valueSet = false;
synchronized int get() {
if(!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) {
if(valueSet)
try {
wait();
} catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.n = n;
valueSet = true;
System.out.println("Put: " + n);
notify();
}
}
class Producer implements Runnable {
Q q;
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}
}
}
class Consumer implements Runnable {
Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
public void run() {
while(true) {
q.get();
}
}
}
class PCFixed {
public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}
}
I have a hard time understanding the usage of a boolean here, if the boolean variable stays, the the code will print correctly.
However if I take away the boolean, then it will ONLY print "Press Control-C to stop". Why is that?
Why is the boolean so important here and what is its usage?
thanks.
The class Q implements a container for one single integer stored in n. This container is used pass that value from the Producer to the Consumer. Since only one value can be kept at a time by the container, both Producer and Consumer must know somehow if the Container is full or not. The boolean value valueSet is this indicator.
If set to true, the container is full, and therefore Producer must wait until it's emptied before filling it again. Likewise, if valueSet is false, the Consumer may not try to retrieve the content of the Q instance until there is something to retrieve.
By removing the boolean (and the tests for its state), you put both Producer and Consumer threads in wait state for a notification (which will likely never happen, since only them were able to generate it in the code), hence the only message appearing is the one from the main thread.
A very important point: as hinted by Freedom_Ben in his own answer, this code works because both get and put methods are made synchronised, meaning that they will block all other threads trying to access the object through synchronized calls during their execution, making these calls atomic with regard to each other. This point is important since it pretty much guarantee that read and write on both valueSet and n are made atomically. Without that property set on both methods, the notification from put might occur after Consumer has checked valueSet but before it calls wait. Depending on the implementation of the notification mechanism (*), this could lead to Consumer missing the notification and going into wait state, even though there's a value in Q.
With the synchronized attribute on these method, we are assured that these calls will behave as intended.
synchronized keyword
notify and wait methods
(*) The wait and notifiy code can be implemented in two ways:
the quick way is to have notify simply check if a thread is waiting, and wake it up if so, or do nothing otherwise. This is the scenario leading to a race condition without properly synchronized method calls.
the more correct way is to use a dedicated semaphore initialized at 0, and alias the notifiy and wait to the increment (aka release) and decrement (aka acquire) operations on the semaphore respectively.
The name of the boolean is valueSet. When it is true, it means that a value has been set. When it is false, it means that a value has not been set. Think of the boolean as a flag, and when it is true there is data to be consumed (the flag is up), when it is false there is no data to be consumed (the flag is down).
The producer thread will set a value only if the flag is false. If it is true, it will wait to be notified by the consumer.
The consumer thread will only read the value if the flag is true. If it is false, it will wait to be notified by the producer.
Do you have access to and experience with a debugger? Stepping through the two threads and seeing how they interact with each other might help you. If you haven't used a debugger before, multithreading might not be the ideal learning scenario.
It looks like the boolean is being used to avoid waiting if the last value hasn't yet been processed. For example, in the put method we are skipping the wait() if valueSet is true, because that means that get() has not yet run since the last time we updated the value of this.n. if we wait() each time regardless of the boolean, chances of a deadlock are pretty good, where both threads are waiting and none will notify.
This is a reason why I don't like applying the synchronized keyword to methods. It can be confusing as to which object is being used as the mutex. I prefer this style because it is more clear which resource is being waited for. I also find that this style discourages lazyiness by doing work under a mutex that doesn't need to be synchronized. It is all personal preference though:
void get(int n){
synchronized(this){
// do the work
}
}
void put(int n){
synchronized(this){
// do the work
}
}
Related
I was trying to implement something similar to Java's bounded BlockingQueue interface using Java synchronization "primitives" (synchronized, wait(), notify()) when I stumbled upon some behavior I don't understand.
I create a queue capable of storing 1 element, create two threads that wait to fetch a value from the queue, start them, then try to put two values into the queue in a synchronized block in the main thread. Most of the time it works, but sometimes the two threads waiting for a value start seemingly waking up each other and not letting the main thread enter the synchronized block.
Here's my (simplified) code:
import java.util.LinkedList;
import java.util.Queue;
public class LivelockDemo {
private static final int MANY_RUNS = 10000;
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < MANY_RUNS; i++) { // to increase the probability
final MyBoundedBlockingQueue ctr = new MyBoundedBlockingQueue(1);
Thread t1 = createObserver(ctr, i + ":1");
Thread t2 = createObserver(ctr, i + ":2");
t1.start();
t2.start();
System.out.println(i + ":0 ready to enter synchronized block");
synchronized (ctr) {
System.out.println(i + ":0 entered synchronized block");
ctr.addWhenHasSpace("hello");
ctr.addWhenHasSpace("world");
}
t1.join();
t2.join();
System.out.println();
}
}
public static class MyBoundedBlockingQueue {
private Queue<Object> lst = new LinkedList<Object>();;
private int limit;
private MyBoundedBlockingQueue(int limit) {
this.limit = limit;
}
public synchronized void addWhenHasSpace(Object obj) throws InterruptedException {
boolean printed = false;
while (lst.size() >= limit) {
printed = __heartbeat(':', printed);
notify();
wait();
}
lst.offer(obj);
notify();
}
// waits until something has been set and then returns it
public synchronized Object getWhenNotEmpty() throws InterruptedException {
boolean printed = false;
while (lst.isEmpty()) {
printed = __heartbeat('.', printed); // show progress
notify();
wait();
}
Object result = lst.poll();
notify();
return result;
}
// just to show progress of waiting threads in a reasonable manner
private static boolean __heartbeat(char c, boolean printed) {
long now = System.currentTimeMillis();
if (now % 1000 == 0) {
System.out.print(c);
printed = true;
} else if (printed) {
System.out.println();
printed = false;
}
return printed;
}
}
private static Thread createObserver(final MyBoundedBlockingQueue ctr,
final String name) {
return new Thread(new Runnable() {
#Override
public void run() {
try {
System.out.println(name + ": saw " + ctr.getWhenNotEmpty());
} catch (InterruptedException e) {
e.printStackTrace(System.err);
}
}
}, name);
}
}
Here's what I see when it "blocks":
(skipped a lot)
85:0 ready to enter synchronized block
85:0 entered synchronized block
85:2: saw hello
85:1: saw world
86:0 ready to enter synchronized block
86:0 entered synchronized block
86:2: saw hello
86:1: saw world
87:0 ready to enter synchronized block
............................................
..........................................................................
..................................................................................
(goes "forever")
However, if I change the notify() calls inside the while(...) loops of addWhenHasSpace and getWhenNotEmpty methods to notifyAll(), it "always" passes.
My question is this: why does the behavior vary between notify() and notifyAll() methods in this case, and also why is the behavior of notify() the way it is?
I would expect both methods to behave in the same way in this case (two threads WAITING, one BLOCKED), because:
it seems to me that in this case notifyAll() would only wake up the other thread, same as notify();
it looks like the choice of the method which wakes up a thread affects how the thread that is woken up (and becomes RUNNABLE I guess) and the main thread (that has been BLOCKED) later compete for the lock — not something I would expect from the javadoc as well as searching the internet on the topic.
Or maybe I'm doing something wrong altogether?
Without looking too deeply into your code, I can see that you are using a single condition variable to implement a queue with one producer and more than one consumer. That's a recipe for trouble: If there's only one condition variable, then when a consumer calls notify(), there's no way of knowing whether it will wake the producer or wake the other consumer.
There are two ways out of that trap: The simplest is to always use notifyAll().
The other way is to stop using synchronized, wait(), and notify(), and instead use the facilities in java.util.concurrent.locks.
A single ReentrantLock object can give you two (or more) condition variables. Use one exclusively for the producer to notify the consumers, and use the other exclusively for the consumers to notify the producer.
Note: The names change when you switch to using ReentrantLocks: o.wait() becomes c.await(), and o.notify() becomes c.signal().
There appears to be some kind of fairness/barging going on using intrinsic locking - probably due to some optimization. I am guessing, that the native code checks to see if the current thread has notified the monitor it is about to wait on and allows it to win.
Replace the synchronized with ReentrantLock and it should work as you expect it. The different here is how the ReentrantLock handles waiters of a lock it has notified on.
Update:
Interesting find here. What you are seeing is a race between the main thread entering
synchronized (ctr) {
System.out.println(i + ":0 entered synchronized block");
ctr.addWhenHasSpace("hello");
ctr.addWhenHasSpace("world");
}
while the other two thread enter their respective synchronized regions. If the main thread does not get into its sync region before at least one of the two, you will experience this live-lock output you are describing.
What appears to be happening is that if both the two consumer threads hit the sync block first they will ping-pong with each other for notify and wait. It may be the case the JVM gives threads that are waiting priority to the monitor while threads are blocked.
Can anyone explain this program on inter-thread communication?
// A correct implementation of a producer and consumer.
class Q {
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();
}
}
class Producer implements Runnable {
Q q;
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}
}
}
class Consumer implements Runnable {
Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
public void run() {
while(true) {
q.get();
}
}
}
class PCFixed {
public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}
}
Output
Put: 1
Got: 1
Put: 2
Got: 2
Put: 3
Got: 3
Put: 4
Got: 4
......
It is very confusing as far as I am concerned, especially the put and get methods where notify() and wait() are used. Please also explain why a boolean value is used.
So there are 2 threads. Qne is setting values on this Q data structure and the other is reading them. Q uses a boolean flag to tell whether a new value is present, the flag gets cleared once an existing value is read.
Q.get uses wait to block until a new value is available to read. Once it's read the new value it sets the flag back to false.
Q.put waits until the other queue has read the new value before setting it to a new value, then lets the other thread know by setting the boolean flag and calling notify.
Remember that wait gives up the lock so the other thread can acquire it.
The boolean flag is needed because a thread may stop waiting without having been notified. Just because a thread woke up doesn't mean it got a notification. Also, even if the thread gets notified, since the thread gave up the lock when it started to wait, the current state of things is unknown (in general there are multithreaded programs where another thread might sneak in and snag something between the time a thread is notified and the time it can regain the lock) so the thread has to re-test the condition again once it has the lock.
Constructs like wait and notify are building blocks for large concurrent programs, so some things may not make as much sense in a small example with only two threads.
See basically its a multithreaded communication with synchronized methods.
simple rquirement here is
1)first allow to write for producer.
2)next allow to read for consumer.
that is controlled using boolean flag valueSet.
in case of producer means put method of Q, logic works this way
if the valueSet is is true means already write is done then ask put method called thread to wait. so it goes to wait until someone calls notify.
ofcourse it wont continue further logic and keeps on waiting for someone to call notify.
coming to reader means get() of Q,
if the valueSet is is false means writter is executing then ask get method called thread to wait. so it goes to wait until someone calls notify.
so once writer completes the execution it calls notify at the end and now reader threads awake and starts reading.
I need to know how wait() and notify() works exactly? I couldn't achieve its working by using wait() and notify() as such. Instead if I use a while() loop for wait, it works properly. How is it so? Why can't I use just wait() and notify() simply?
have you read the documentation of the wait-notify functions ?
anyway, for the best way to achieve a wait-notify mechanism, use something like this (based on this website) :
public class WaitNotifier {
private final Object monitoredObject = new Object();
private boolean wasSignalled = false;
/**
* waits till another thread has called doNotify (or if this thread was interrupted), or don't if was already
* notified before
*/
public void doWait() {
synchronized (monitoredObject) {
while (!wasSignalled) {
try {
monitoredObject.wait();
} catch (final InterruptedException e) {
break;
}
}
wasSignalled = false;
}
}
/**
* notifies the waiting thread . will notify it even if it's not waiting yet
*/
public void doNotify() {
synchronized (monitoredObject) {
wasSignalled = true;
monitoredObject.notify();
}
}
}
do note, that each instance of this class should be used only once, so you might want to change it if you need to use it multiple times.
wait() and notify() are used in synchronized block while using threads to suspend and resume where left off.
Wait immediately looses the lock, whereas Nofity will leave the lock only when the ending bracket is encountered.
You can also refer this sample example:
public class MyThread implements Runnable {
public synchronized void waitTest() {
System.out.println("Before Wait");
wait();
System.out.println("After Wait");
}
public synchronized void notifyTest() {
System.out.println("Before Notify");
notify();
System.out.println("After Notify");
}
}
public class Test {
public static void main(String[] args) {
Thread t = new Thread(new MyThread());
t.start();
}
}
I think you are asking why does it work with while loop and does not without.
The answer is when your program calls wait() the operation system suspends your thread and activates (starts) another, and there will happen so called context switch.When OS suspend a thread it needs to save some "meta data" about your thread in order to be able to resume that thread later, PC register is what will answer your question.Basically PC (Program Counter) is a pointer to next instruction which the thread should do or is going to do, after being resumed a thread uses it to understand which instruction it was going to do when OS suspended him, and continues by that instruction (in this case, if you want to look at it by the means of Java program, the next instruction will be the next line after call to wait()).As written in "Java Concurrency in Practice"
Every call to wait is implicitly associated with a specific condition predicate. When calling wait regarding a particular
condition predicate, the caller must already hold the lock associated with the condition queue, and that lock must also
guard the state variables from which the condition predicate is composed.
Because your thread waits because some condition was not met (it should be) after returning to the method that it was suspended in, it needs to recheck that condition to see is it met yet.If condition is met it will not wait anymore, if it's not met it will call wait() again ( as it is in while loop).The important thing to know here is
PC (Program Counter) concept
and
The fact that a Thread that calls wait() on your method will not exit the method -> wait -> get resumed again -> call the method again, instead it will wait -> get resumed again -> continue from the point (instruction/line) where it was suspended (called wait())
I have two threads and I am currently doing locking using an Object's notify() and wait() methods inside Synchronized blocks. I wanted to make sure that the main thread is never blocked so I used a boolean this way (only relevant code provided.)
//Just to explain an example queue
private Queue<CustomClass> queue = new Queue();
//this is the BOOLEAN
private boolean isRunning = false;
private Object lock;
public void doTask(){
ExecutorService service = Executors.newCachedThreadPool();
//the invocation of the second thread!!
service.execute(new Runnable() {
#Override
public void run() {
while(true){
if (queue.isEmpty()){
synchronized (lock){
isRunning = false; //usage of boolean
lock.wait();
}
}
else{
process(queue.remove());
}
}
});
}
//will be called from a single thread but multiple times.
public void addToQueue(CustomClass custObj){
queue.add(custObj);
//I don't want blocking here!!
if (!isRunning){
isRunning = true; //usage of BOOLEAN!
synchronized(lock){
lock.notify();
}
}
}
Does anything seems wrong here? thanks.
Edit:
Purpose: This way when add() will be called the second time and more, it won't get blocked on notify(). Is there a better way to achieve this non blocking behavior of the main thread?
Although you do not show the addToQueue code I am fairly certain that this code will not work properly, as you are accessing the shared queue (which is not thread-safe) without any synchronization.
process(queue.remove());
Instead of trying to make your custom queue work (I doubt that your plan with the boolean flag is possible), save the time and work and use one of the BlockingQueues or ConcurrentLinkedQueue provided in the JDK.
The Queue is not synchronized and therefore the above code can suffer from the lost wake-up call typical for conditional variables and monitors. https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem
For example, here is a problematic sequence:
At the beginning of the run the Q is empty and isRunning is false.
Thread 1 (t1) checks if Q is empty (which is true) and then stops running.
Than Thread 2 (t2) starts running and execute the addToQ method.
and then t1 continues running and waits on the lock although the Q is not empty.
If you want a non-blocking solution you can use the non-blocking Q java is offering (http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html)Of course, you can use java own blockingQueue, but this is blocking.
I am fairly new to JAVA and especially concurrency, so probably/hopefully this is fairly straight forward problem.
Basically from my main thread I have this:
public void playerTurn(Move move)
{
// Wait until able to move
while( !gameRoom.game.getCurrentPlayer().getAllowMove() )
{
try {
Thread.sleep(200);
trace("waiting for player to be available");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
gameRoom.getGame().handle(move);
}
gameRoom.getGame() is on its own thread.
gameRoom.getGame().handle() is synchronized
gameRoom.game.getCurrentPlayer() is on a varible of gameRoom.getGame(), it is in the same thread
allowMoves is set to false as soon as handle(move) is called, and back to true once it has finished processing the move.
I call playerTurn() multiple times. I actually call it from a SmartFoxServer extension, as and when it receives a request, often in quick succession.
My problem is, most times it works. However SOMETIMES it is issuing multiple handle(move) calls even though allowMoves should be false. Its not waiting for it to be true again. I thought its possible that the game thread didn't have a chance to set allowMoves before another handle(move) was called. I added volatile to allowMoves, and ensured the functions on the game thread were set to synchronized. But the problem is still happening.
These are in my Game class:
synchronized public void handle(Object msg)
{
lastMessage = msg;
notify();
}
synchronized public Move move() throws InterruptedException
{
while (true)
{
allowMoves = true;
System.out.print(" waiting for move()...");
wait();
allowMoves = false;
if (lastMessage instanceof Move)
{
System.out.print(" process move()...");
Move m = (Move) lastMessage;
return m;
}
}
}
public volatile boolean allowMoves;
synchronized public boolean getAllowMoves()
{
return allowMoves;
}
As I said, I am new to this and probably a little ahead of myself (as per usual, but its kinda my style to jump into the deep end, great for a quick learning curve anyway).
Cheers for your help.
Not sure if this will help, but what if you will use AtomicBoolean instead of synchronized and volatile? It says that it is lock-free and thread-safe.
The Problem is you are using synchronized method on two different objects.
gameRoom.game.getCurrentPlayer().getAllowMove()<-- This is synchronized on
CurrentPlayer instance.
gameRoom.getGame().handle(move)<-- This is synchronized on `gameRoom.getGame()`
This is your issue. You don't need synchronized keyword for getAllowMoves since field is volatile as volatile guarantees visibility semantics.
public boolean getAllowMoves() {
return allowMoves;
}
there is the primitive, dedicated for resource management - Semaphore
you need to
create semaphore with permits set to 1
use acquire when looking for a move
use release after move is complete
so you will never face that 2 concurrent invocations of handle method appear.