Deadlock in the semaphore function - java

Question 1:
I was reading into Hard-core Multi-threading in Java and did bump up into the semaphore example below.
package com.dswgroup.conferences.borcon.threading;
public class ResourceGovernor {
private int count;
private int max;
public ResourceGovernor(int max) {
count = 0;
this.max = max;
}
public synchronized void getResource(int numberof) {
while (true) {
if ((count + numberof) <= max) {
count += numberof;
break;
}
try {
wait();
} catch (Exception ignored) {}
}
}
public synchronized void freeResource(int numberof) {
count -= numberof;
notifyAll();
}
}
I feel this can lead to deadlock in the below scenario :
All resources are being used and a new thread asks for resources that are not available.
Since it waits inside the synchronized function, the other threads that are using the resources are not able to free the resources as the freeResource function is also synchronized and that they can't enter the function as the waiting thread has taken the object level lock of ResourceGovernor
There is another issue that one has not validated if a thread is trying to release more no. of resources than it acquired. But this issue is secondary and can be easily fixed by having the synchronized map of thread name and resource count.
But can i safely say that i diagnosed the 1st problem correctly. (Need to doublecheck since its published for a long time on embarcadero.com)
Question 2:
Can i safely say that a semaphore with only 1 resource has the same behaviour as a mutex lock?

All resources are being used and a new thread asks for resources that are not available. Since it waits inside the synchronized function, the other threads that are using the resources are not able to free the resources as the freeResource function is also synchronized and that they can't enter the function as the waiting thread has taken the object level lock of ResourceGovernor
You've missed the fact that calling wait() relinquishes the monitor, so other synchronized code is able to execute. From the docs 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.
For your second question:
Can I safely say that a semaphore with only 1 resource has the same behaviour as a mutex lock?
I suspect so, although the implementation you've shown doesn't actually stop you from calling freeResource several times. It's a slightly odd implementation in that I normally see semaphores counting the number of resources remaining rather than the number of resources taken - although they're equivalent, of course.

Question 2 : Yes it is similar to mutex. But although mutexes and semaphores have similarities in their implementation, they should always be used differently. Nice Explanation Here

Related

How to use synchronized in java

I hope I can understandably describe the situation.
I want to start some amount of threads and all of them will execute one synchronized method. Consider first thread checks value of a variable in this method then the lock will be released after check.Then the second thread calls the same function. But first thread will then (after some ms) modify this variable which is in another class but second thread will (maybe) check the variable before the first changed it. How can I force the second thread to wait (without sleep) till the first has finished and changed the variable before the second checks the value? Can the first send some signal like "variable changed, u can check it now"?
Now I try to write this in code: threads started all all do this run:
abstract class Animal {
protected House house;
abstract boolean eating();
#Override
public void run() {
try {
while(!Thread.interrupted()) {
if(eating()) {
goEat();//here house.eatingRoom.count will be changed
Thread.sleep(1000);
goback();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
All of them access this method:
class Cat extends Animal {
#Override
synchronized boolean eating() {
if (house.eatingRoom.count == 0)
return true;//first thread release lock and 2 thread access it but the value is not changed yet
else
return false;
}
}
And:
class EatingRoom {
final Set<Animal> count = new HashSet<>();
synchronized void add(Cat c) {
count.add(c);
}
}
to complete:
public class House extends Thread {
final EatingRoom eatingRoom = new EatingRoom();
//start all threads here so run in Animal class is executed..
}
The problem you are describing sounds like you could benefit from the Java synchronisation primitives like Object.wait and Object.notify.
A thread that owns the lock/monitor of a given object (such as by using the synchronized keyword) can call wait instead of looping and sleeping in a busy/wait pattern like you have in while(!Thread.interrupted()) which may waste many CPU cycles.
Once the thread enters the wait state it will release the lock it holds, which allows another thread to acquire that same lock and potentially change some state before then notifying one or more waiting threads via notify/notifyAll.
Note that one must be careful to ensure locks are acquired and released in the same order to help avoid deadlock scenarios when more than one lock is involved. Consider also using timeouts when waiting to ensure that your thread doesn't wait indefinitely for a condition that might never arise. If there are many waiting threads when you call notify be aware that you might not know which thread will be scheduled but you can set a fairness policy to help influence this.
Depending on the structure of your code you may be able to avoid some of the lower level primitives like synchronised blocks by using some higher level APIs such as https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/Lock.html or keywords like volatile for variables that contain shared mutable state (like a condition you want to wait for to ensure the result of a write is observed on a subsequent read in a "happens before" relationship.

In Java, what is the difference between a monitor and a lock

Using the synchronized keyword method, using the javap command to view the bytecode, it is found that monitor is used, and if it is possible to call the monitor when the synchronized is implemented, is that my understanding, right? Please correct it if you do not. What is the relationship between them? What is the relationship between the lock and the monitor?
From the official documentation of Locks and Synchronization:
Synchronization is built around an internal entity known as the intrinsic lock or monitor lock. (The API specification often refers to this entity simply as a "monitor.")
Every object has an intrinsic lock associated with it. By convention, a thread has to acquire the object's monitor lock
before accessing them, and then release the monitor lock when it's
done with them. A thread is said to own the lock between the time it
has acquired the lock and released the lock. As long as a thread owns
a monitor lock, no other thread can acquire the same lock. The other
thread will block when it attempts to acquire the lock.
When a thread releases the lock, a happens-before relationship is established between that action and any subsequent acquisition of the
same lock.
So a monitor and a lock can not be compared for differences, rather they are complementary to each other. Every object in Java is associated with a monitor which a thread can lock or unlock.
Locks
A lock is kind of data which is logically part of an object’s header on the heap memory. Each object in a JVM has this lock (or mutex) that any program can use to coordinate multi-threaded access to the object. If any thread want to access instance variables of that object; then thread must “own” the object’s lock (set some flag in lock memory area). All other threads that attempt to access the object’s variables have to wait until the owning thread releases the object’s lock (unset the flag).
Once a thread owns a lock, it can request the same lock again multiple times, but then has to release the lock the same number of times before it is made available to other threads. If a thread requests a lock three times, for example, that thread will continue to own the lock until it has “released” it three times.
Please note that lock is acquired by a thread, when it explicitly ask for it. In Java, this is done with the synchronized keyword, or with wait and notify.
Monitors
Monitor is a synchronization construct that allows threads to have both mutual exclusion (using locks) and cooperation i.e. the ability to make threads wait for certain condition to be true (using wait-set).
In other words, along with data that implements a lock, every Java object is logically associated with data that implements a wait-set. Whereas locks help threads to work independently on shared data without interfering with one another, wait-sets help threads to cooperate with one another to work together towards a common goal e.g. all waiting threads will be moved to this wait-set and all will be notified once lock is released. This wait-set helps in building monitors with additional help of lock (mutex).
For more clarification refer -
UNDERSTANDING THREADS, MONITORS AND LOCKS
Difference between lock and monitor – Java Concurrency
The doc https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html might not be a very good place to figure out the difference between Lock and Monitor, especially the terms it mentioned: intrinsic lock, monitor lock and simply monitor, which seems suggest that monitor and lock are interchangeable.
This is not true.
Monitor is a structure used for multi-thread synchronization. It consists of a lock and several condition variables. A condition variable is a queue that threads can put them on when a given condition is not as desired. Some other thread can wake these threads up when it makes the condition true. Condition Variable is a way helps threads cooperating with each other.
In simple synchronization cases, we only make use of the lock the monitor provided, like this example:
class SimpleCase {
int counter;
synchronized inc() int {
return counter++;
}
}
Threads doing inc() needs no cooperation, only lock is needed to make the threads mutually exclusive, thus makes the counter thread safe.
While in more complicated cases, no only mutual exclusion(mutex) is needed, but also cooperation.
For example, the bounded consumer/producer problem: multi consumers and producers consume and send messages to a queue. Cooperation is needed cause the message queue has a max size, when the queue is full, no more messages can be sent, and when the queue is empty, no more messages can be consumed.
Below is the code showing the producer:
package monitor;
public class Producer {
BoundedQueue queue;
public Producer(BoundedQueue queue) {
this.queue = queue;
}
public void send(int msg) throws InterruptedException {
synchronized (queue) {
// wait till there is room to produce
while (queue.isFull()) {
queue.wait();
}
// business logic here
queue.add(msg);
System.out.println("sent:" + msg + ", from:" + Thread.currentThread().getName());
// before exit, call notify() to wake up waiting threads
queue.notifyAll();
}// implicit release the lock when exiting the synchronized block
}
}
In the code, the BoundedQueue is used as a monitor, except for mutual exclusion, producers and consumers also need cooperation: when queue is full, producers need to wait(), and when queue has available slots, producers need to be notified to wake up from the wait, after producer send data to the queue, it also needs to call notifyAll() in case there are consumers waiting for the condition that the queue is not empty.
Here, the ability to wait and notify is provided by Monitor to make threads cooperate.
Hope this helps you understand the difference between Monitor and Lock.
Ref:
https://en.wikipedia.org/wiki/Monitor_(synchronization)
http://pages.cs.wisc.edu/~remzi/OSTEP/threads-cv.pdf
In this document, you can find the answer to your question:
Synchronization. The Java programming language provides multiple
mechanisms for communicating between threads. The most basic of these
methods is synchronization, which is implemented using monitors. Each
object in Java is associated with a monitor, which a thread
can lock or unlock.
A monitor is a combination of mutual exclusion, the ability to wait for an external condition to be true, and the ability to notify other threads of that event.
The condition and notification pieces are essentially cooperation
A lock provides mutual exclusion. This means it prevents multiple threads from accessing the same data at the same time.
Notice a monitor uses mutual exclusion. Therefore, locks are used to implement monitors.
The other answers provide definitions of these two. Let's visualise a practical use case:
public class Test {
public synchronized static void testMonitor() throws InterruptedException {
Thread.sleep(1000);
System.out.println("done");
}
public static void testLock(Object lock) throws InterruptedException {
synchronized (lock){
Thread.sleep(1000);
System.out.println("done");}
}
public static void main(String[] args) throws InterruptedException {
long start = System.currentTimeMillis();
List<Thread> threadList = new ArrayList<>();
for(int i=0 ;i< 10; i++){
Thread thread = new Thread(() -> {
try {
Test.testMonitor();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
threadList.add(thread);
thread.start();
}
for(int i=0 ;i< 10; i++){
threadList.get(i).join();
}
long end = System.currentTimeMillis();
System.out.println((end - start)/1000);
}
public static void main(String[] args) throws InterruptedException {
long start = System.currentTimeMillis();
List<Thread> threadList = new ArrayList<>();
for(int i=0 ;i< 10; i++){
Object lock = new Object();
Thread thread = new Thread(() -> {
try {
Test.testLock(lock);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
threadList.add(thread);
thread.start();
}
for(int i=0 ;i< 10; i++){
threadList.get(i).join();
}
long end = System.currentTimeMillis();
System.out.println((end - start)/1000);
}}
The first method testMonitor uses monitor(intrinsic lock). Running 1st main method will print execution time as 10 seconds.
The second method testLock uses object lock. Running 2nd main method will print execution time as 1 seconds.

How do objects with synchronized methods and synchronized statements resemble monitors and conditional critical regions respectively?

From Programming Language Pragmatics, by Scott
Java objects that use only synchronized methods (no locks or
synchronized statements) closely resemble Mesa monitors in which
there is a limit of one condition variable per monitor (and in fact
objects with synchronized statements are sometimes referred to as
monitors in Java).
Why are Java objects that use only synchronized methods closely resemble Mesa monitors in which there is a limit of one condition variable per monitor?
Is it correct that there is no condition variable in "Java objects that use only synchronized methods"? So how can it resembles a monitor with one condition variable?
By the same token, a synchronized statement in Java that begins
with a wait in a loop resembles a CCR in which the retesting of
conditions has been made explicit. Because notify also is explicit,
a Java implementation need not reevaluate conditions (or wake up
threads that do so explicitly) on every exit from a critical
section—only those in which a notify occurs.
Why does a synchronized statement in Java that begins
with a wait in a loop resembles a CCR (conditional critical region) in which the retesting of conditions has been made explicit?
What does it mean by "Because notify also is explicit, a Java implementation need not reevaluate conditions (or wake up threads that do so explicitly) on every exit from a critical section—only those in which a notify occurs"?
Thanks.
All this is saying is that in Java intrinsic locks have the condition baked into them. Contrast this with ReentrantLock where you can explicitly have separate conditions with the same lock.
If you have separate conditions then you can signal a given condition and know only threads in the wait set for that condition will receive it. If you don't have separate condition objects then upon being notified you have to check to see if that condition applies to you.
An example of this would be a fixed size blocking queue. If you look at ArrayBlockingQueue, it's implemented with ReentrantLock so that putting and taking use separate condition objects. If this was implemented using the intrinsic lock on the Queue object it would have to use notifyAll to wake up waiting threads, which would then have to test the condition they woke up from waiting on to find out if it was relevant to them.
Here is a blocking queue written using an intrinsic lock. If notify was used then a single thread would be woken by the scheduler and (since threads could be waiting to put or waiting to take) it might or might not be one that the notify was relevant to. To make sure the notification doesn't get lost all the waiting threads get notified:
public class Queue<T>{
private final int maxSize;
private List<T> list = new ArrayList<>();
public Queue(int maxSize) {
this.maxSize = maxSize;
}
public synchronized T take() throws InterruptedException {
while (list.size() == 0) {
wait();
}
notifyAll();
return list.remove(0)(
}
public synchronized void put(T entry) throws InterruptedException {
while (list.size() == maxSize) {
wait();
}
list.add(entry);
notifyAll();
}
}

Confused with custom read write lock implementation

I have seen some posts about the custom read-write lock implementation in java using wait/notify. It looks like:
public class ReadWriteLock{
private int readers;
private int writers;
private int writeRequests;
public synchronized void lockRead() throws InterruptedException{
while(writers > 0 || writeRequests > 0){
wait();
}
readers++;
}
public synchronized void unlockRead(){
readers--;
notifyAll();
}
public synchronized void lockWrite() throws InterruptedException{
writeRequests++;
while(readers > 0 || writers > 0){
wait();
}
writeRequests--;
writers++;
}
public synchronized void unlockWrite() throws InterruptedException{
writers--;
notifyAll();
}
}
I cannot comprehend how it could correctly work, unless I have not understood correctly how wait/notify really works. Assuming the read requests and consequently Threads are more, my questions are:
If read Threads acquire repeatedly the lock on the instance, how could a write Thread increase the variable writeRequests, since it can be increased only within a synchronized method. Hence a Thread should acquire first the lock to do it (if I am not mistaken). As long as a read Thread calls wait only if writeRequests or writers are greater than 0 , how can a write Thread have the chance to acquire the lock?
Based on the above presumptions and statements, how could more than one read Threads access a method at the same time, since they should first call lockRead() which is synchronized as well?
Edit : After seeing you edit to the question, you're asking what happens when multiple threads call wait() inside the same synchronized blocks - see this for a detailed explanation on what is called 'releasing the monitor' - http://www.artima.com/insidejvm/ed2/threadsynchP.html
To simplify things:
Synchronized methods are like synchronized(this) blocks.
calling wait() inside synchronized blocks release the lock and switches the thread to WAITING state. in this scenario other threads can acquire the lock on the same object and possibly notify the other waiting threads on state change (your unlock methods demonstrate that) by using the same object waited on (this in our case, because you're using synchronized methods)
If you map the possible scenarios for calling each method according to that priniciple you can see that methods are either non-waiting ( unlockRead()/unlockWrite()) - meaning they can block on mutual exclusion upon entry, but don't run any blocking code(and end swiftly).
Or, they are waiting but non-blocking ( lockRead()/lockWrite()) - Just like the unlock methods with the addition their execution could potentially be stalled, however they don't block, but rather wait in such scenarios.
So in any case you can consider your code as non-blocking and therefor it doesn't pose any real issue ( at least none that I can see ).
That said, you should protect against unlocking non-existent locks, causes that'll cause an undesired behavior where counters would go below 0 ( which would in turn affect the lock methods)

how to safely increment while using threads in java

hi guys i was wondering if i can get a little advice im trying to write a program that can counts how many threads are waiting to process a function, and then once a certain number is achieved it releases all the thread. but my problem is i cant increment properly being that i can the all process the increment code at the same time , thus not incrementing it at all.
protected synchronized boolean isOpen()
{
//this code just calls mymethod intrested where the problem lies
lock.interested();
while(!lock.isReady())
{
}
return true;// this statement releases all my threads
}
public synchronized void interested()
{
count++;// how do i make this increment correctly with threads
System.out.println(count+"-"+ lanes+"-"+ThreadID.get());
if(count==lanes)
{
count =0;
ready =true;
}
}
The problem with your approach is that only one thread can enter the synchronized method at a time and hence, you will never proceed, as all but the first threads are waiting to enter the synchronized method while the first thread is performing a busy-wait loop. You have to use wait which not only solves the waste of CPU cycles of your busy wait but will also free the associated lock of the synchronized code so that the next thread can proceed:
protected synchronized boolean isOpen()
{
lock.interested();
while(!lock.isReady())
{
wait(); // now the next thread can enter isOpen()
}
notify(); // releases the previous thread wait()ing in this method
return true;
}
However, note that this works quite unreliable due to your code being split over multiple different objects. It’s strongly recommend to put the code maintaining the counter and code implementing the waiting for the counter into one object in order to run under the same lock. Your code structure must ensure that interested() can’t be invoked on the lock instance with isOpen not noticing. From the two code fragments you have posted, it’s impossible to deduce whether this is the case.
write a program that can counts how many threads are waiting to
process a function, and then once a certain number is achieved it
releases all the threads
A good solution will be to use CountDownLatch.
From the manual:
A CountDownLatch is initialized with a given count. The await methods
block until the current count reaches zero due to invocations of the
countDown() method, after which all waiting threads are released and
any subsequent invocations of await return immediately. This is a
one-shot phenomenon -- the count cannot be reset. If you need a
version that resets the count, consider using a CyclicBarrier.
You can find a good code example here
You should not use synchronised. Because only one thread will acquire monitor at a time.
You can use CountDownLatch. Just define the no of threads while initialising CountDownLatch.
private CountDownLatch countDownLatch = new CountDownLatch(no_of_threads);
protected boolean isOpen()
{
//this code just calls mymethod intrested where the problem lies
countDownLatch.countDown();
countDownLatch.await();
return true;// this statement releases all my threads
}
All the threads are waiting in countDownLatch.await(). Once the required amount of thread comes(countDownLatch.countDown() is called) it will allow to proceed.

Categories