Java wait() and notifyAll() resume oldest Thread - java

My problem:
Lets say that i have class A with some variable a
And class B with variables prev and next
In class A i want to make method changeIfEqual(B myB) which checks if A.a == my_B.prev, if so i change A.a to my_B.next. But if A.a != my_B.prev i want thread to wait() until continion is true and then execute the thread that have been waining for the longest time.
So I imagine A.changeIfEqual(B myB) should look like this:
public synchronized void changeIfEqual(B myB){
while(this.a != myB.b_prev){
wait();
}
notifyAll();
}
In this case the problem is how can I ensure that the oldest thread would be resume? (wait() and notifyAll() dont provide that)

You don’t. Which thread gets notified is up to the scheduler. If you replace the implicit locking (using synchronized) with ReentrantLock, then you can specify that the lock is fair. But that's not a perfect solution, see the API docs:
The constructor for this class accepts an optional fairness parameter. When set true, under contention, locks favor granting access to the longest-waiting thread. Otherwise this lock does not guarantee any particular access order. Programs using fair locks accessed by many threads may display lower overall throughput (i.e., are slower; often much slower) than those using the default setting, but have smaller variances in times to obtain locks and guarantee lack of starvation. Note however, that fairness of locks does not guarantee fairness of thread scheduling. Thus, one of many threads using a fair lock may obtain it multiple times in succession while other active threads are not progressing and not currently holding the lock. Also note that the untimed tryLock method does not honor the fairness setting. It will succeed if the lock is available even if other threads are waiting.

If you absolutely must wake "consumer" threads in a particular order,* the thing to do would be to give each consumer its own Semaphore, and have each consumer put a reference to its semaphore into a queue before awaiting it.
class MyConsumer {
private final Queue<Semaphore> sleep_q;
private final Semaphore sleep_sem = new Semaphore(0);
public MyConsumer(Queue sleep_q) {
this.sleep_q = sleep_q;
}
private void waitToBeNotified() {
sleep_q.add(sleep_sem);
sleep_sem.acquire();
}
public void whatever() {
doSomeStuff();
waitToBeNotified();
doSomeMoreStuff();
}
The producer can awaken the longest-waiting thread by popping a semaphore from the queue, and releasing a permit to it.
class MyProducer {
private final Queue<Semaphore> sleep_q;
public MyConsumer(Queue sleep_q) {
this.sleep_q = sleep_q;
}
public void goForthAndProduceStuff() {
while (...) {
produceSomething();
awakenAConsumer();
}
}
private void awakenAConsumer() {
Semaphore sem = sleep_q.poll();
if (sem != null) {
sem.release();
}
}
}
* But, see my comment on the original question.

Related

What happens when few threads trying to call the same synchronized method?

so I got this horses race and when a horse getting to the finishing line, I invoke an arrival method. Let's say I got 10 threads, one for each horse, and the first horse who arrives indeed invoking 'arrive':
public class FinishingLine {
List arrivals;
public FinishingLine() {
arrivals = new ArrayList<Horse>();
}
public synchronized void arrive(Horse hourse) {
arrivals.add(hourse);
}
}
Ofc I set the arrive method to synchronized but I dont completely understand what could happen if it wasnt synchronized, the professor just said it wouldn't be safe.
Another thing that I would like to understand better is how it is decided which thread will after the first one has been finished? After the first thread finished 'arrive' and the method get unlocked, which thread will run next?
1) It is undefined what the behaviour would be, but you should assume that it is not what you would want it to do in any way that you can rely upon.
If two threads try to add at the same time, you might get both elements added (in either order), only one element added, or maybe even neither.
The pertinent quote from the Javadoc is:
Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements, or explicitly resizes the backing array; merely setting the value of an element is not a structural modification.)
2) This is down to how the OS schedules the threads. There is no guarantee of "fairness" (execution in arrival order) for regular synchronized blocks, although there are certain classes (Semaphore is one) which give you the choice of a fair execution order.
e.g. you can implement a fair execution order by using a Semaphore:
public class FinishingLine {
List arrivals;
final Semaphore semaphore = new Semaphore(1, true);
public FinishingLine() {
arrivals = new ArrayList<Horse>();
}
public void arrive(Horse hourse) {
semaphore.acquire();
try {
arrivals.add(hourse);
} finally {
semaphore.release();
}
}
}
However, it would be easier to do this with a fair blocking queue, which handles the concurrent access for you:
public class FinishingLine {
final BlockingQueue queue = new ArrayBlockingQueue(NUM_HORSES, true);
public void arrive(Horse hourse) {
queue.add(hourse);
}
}

Is there a way to include a Condition to adquire method in java (or scala) Semaphore object?

I have a program that holds many threads, lets put as an example six threads. Five of them should be able to use concurrently a given resource but the last thread shouldn't if a given condition occurs and should wait until that condition is over.
In my understanding a ReentrantLock can't be used because it can only be held by one thread at a time. In the other hand a Semaphore can be held by many threads at a time but I can't find a way to attach the condition to aquire method.
Can This high level objects do the trick or I will have to implement this functionality using notify and wait directly?
Eg.
class A{
getResource{ ... }
}
//This Runable could be spawn many times at the same time
class B implements Runnable{
run {
setConditionToTrue
getResource
...
getResource
...
getResource
setConditionToFalse
}
}
//This will be working forever but only one Thread
class C implements Runnable{
run{
loop{
if(Condition == true) wait
getResource
}
}
}
Thanks in advance pals
I am restating your problem here: You want your B threads to access the shared resource concurrently, but your C thread should wait for some condition to occur before using the resource.
If I understand your question correctly, You can use ReentrantLock to solve your problem.
Introduce a new function called getAccess() and make the C thread call this function to get the shared resource. Introduce two more functions to allow and stop the access to shared resource.
class A {
private final ReentrantLock lock = new ReentrantLock();
private Condition someCondition = lock.newCondition();
private boolean bCondition = false;
getResource{ ... } // Your existing method used by B threads
getAccess() { // Protected access to some resource, called by C thread
lock.acquire();
try {
if (!bCondition)
someCondition.await(); // B thread will wait here but releases the lock
} finally {
lock.release();
}
}
allowAccess() { // B thread can call this func to notify C and allow access
lock.acquire();
try {
bCondition = true;
someCondition.signal(); // Decided to release the resource
} finally {
lock.release();
}
}
stopAccess() { // B thread can stop the access
lock.acquire();
try {
bCondition = false;
} finally {
lock.release();
}
}
}
If you want several threads to share a resource, you need to be more specific about the meaning of that sharing. Normally this means differentiating between those threads that read the current value of the resource and other threads that change the value. This implies is a concurrent-read / exclusive-write pattern ('crew') if the writes are to be race-free and stable.
In the Java API, this is provided by the ReentrantReadWriteLock. There are also other alternatives worthy of consideration, such as the carefully-implemented Crew in JCSP.
Using [J]CSP, a different pattern is also available: that of wrapping the common resource in its own thread and providing access to it via a shared JCSP channel from all the client threads. This client-server pattern is easy to understand and implement, and has the added benefit that it is formally deadlock-free, given that the thread communication graph is acyclic (more).

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

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.

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

Two BlockingQueue - deadlock

I have a requirement to manipulate two queues atomically and am not sure what is the correct synchronization strategy: This is what I was trying:
public class transfer {
BlockingQueue firstQ;
BlockingQueue secondQ;
public moveToSecond() {
synchronized (this){
Object a = firstQ.take();
secondQ.put(a)
}
}
public moveToFirst() {
synchronized(this) {
Object a = secondQ.take();
firstQ.put(a);
}
}
}
Is this the correct pattern? In the method moveToSecond(), if firstQ is empty, the method will wait on firstQ.take(), but it still holds the lock on this object. This will prevent moveToFirst() to have a chance to execute.
I am confused about the lock release during a wait - Does the thread release all locks [both this and BlockedQUeue lock?]? What is the correct pattern to provide atomicity dealing with multiple blocking queues?
You are using the correct approach using a common mutex to synchronize between both queues. However, to avoid the situation you describe with the first queue being empty I'd suggest reimplementing moveToFirst() and moveToSecond() to use poll() rather than take(); e.g.
public void boolean moveToFirst() {
// Synchronize on simple mutex; could use a Lock here but probably
// not worth the extra dev. effort.
synchronzied(queueLock) {
boolean success;
// Will return immediately, returning null if the queue is empty.
Object o = firstQ.poll();
if (o != null) {
// Put could block if the queue is full. If you're using a bounded
// queue you could use add(Object) instead to avoid any blocking but
// you would need to handle the exception somehow.
secondQ.put(o);
success = true;
} else {
success = false;
}
}
return success;
}
Another failure condition you didn't mention is if firstQ is not empty but secondQ is full, the item will be removed from firstQ but there will be no place to put it.
So the only correct way is to use poll and offer with timeouts and code to return things to the way they were before any failure (important!), then retry after a random time until both poll and offer are successful.
This is an optimistic approach; efficient in normal operation but quite inefficient when deadlocks are frequent (average latency depends on the timeout chosen)
You should use the Lock-mechanism from java.util.concurrency, like this:
Lock lock = new ReentrantLock();
....
lock.lock();
try {
secondQ.put(firstQ.take());
} finally {
lock.unlock();
}
Do the same for firstQ.put(secondQ.take()), using the same lock object.
There is no need to use the lowlevel wait/notify methods on the Object class anymore, unless you are writing new concurrency primitives.
In your code, while the thread is blocked on BlockingQueue.take() it is holding on to the lock on this. The lock isn't released until either the code leaves the synchronized block or this.wait() is called.
Here I assume that moveToFirst() and moveToSecond() should block, and that your class controls all access to the queues.
private final BlockingQueue<Object> firstQ = new LinkedBlockingQueue();
private final Semaphore firstSignal = new Semaphore(0);
private final BlockingQueue<Object> secondQ = LinkedBlockingQueue();
private final Semaphore secondSignal = new Semaphore(0);
private final Object monitor = new Object();
public void moveToSecond() {
int moved = 0;
while (moved == 0) {
// bock until someone adds to the queue
firstSignal.aquire();
// attempt to move an item from one queue to another atomically
synchronized (monitor) {
moved = firstQ.drainTo(secondQ, 1);
}
}
}
public void putInFirst(Object object) {
firstQ.put(object);
// notify any blocking threads that the queue has an item
firstSignal.release();
}
You would have similar code for moveToFirst() and putInSecond(). The while is only needed if some other code might remove items from the queue. If you want the method that removes on the queue to wait for pending moves, it should aquire a permit from the semaphore, and the semaphore should be created as a fair Semaphore, so the first thread to call aquire will get released first:
firstSignal = new Semaphore(0, true);
If you don't want moveToFirst() to block you have a few options
Have the method do do its work in a Runnable sent to an Executor
Pass a timeout to moveToFirst() and use BlockingQueue.poll(int, TimeUnit)
Use BlockingQueue.drainTo(secondQ, 1) and modify moveToFirst() to return a boolean to indicate if it was successful.
For the above three options, you wouldn't need the semaphore.
Finally, I question the need to make the move atomic. If multiple threads are adding or removing from the queues, then an observing queue wouldn't be able to tell whether moveToFirst() was atomic.

Categories