Consider the following code :-
class CalculateSeries implements Runnable{
int total;
public void run(){
synchronized(this){ // *LINE 1*
for(int i = 1; i <= 10000; i++) {
total += i;
}
notify(); //Notify all the threads waiting on this instance of the class to wake up
}
}
}
Another class is waiting on an instance of this class by getting the lock on it inside a synchronized block. But if I don't keep the code in run method in a synchronized block, then I get IllegalMonitorStateException.
notify() should mean to give signal to all the threads waiting. Then why should it be inside synchronized block?
notify() should mean to give signal to all the threads waiting.
Actually, no. It signals one arbitrarily chosen waiting thread. notifyAll() signals all of them.
Then why should it be inside synchronized block?
Because waiting doesn't happen for its own sake. You check for a condition and if it's not met, you wait until someone tells you it may now be met (then you check again). Without synchronization, you would have race conditions between checking the condition and actually waiting.
if notify() method is not within synchronized block then it would be useless to place wait() into synchronized block.
Take scenario of producer-consumer model, producer and consumer both the methods will execute concurrently because one of them is not synchronized. There will be a race condition.
Related
The Object#wait() method has this funny property that it will allow other threads to enter it's synchronized block while it is blocked in it. Example (assume thread 1 runs first):
Thread 1:
synchronized(someLock)
{
wait();
}
Thread 2:
synchronized(someLock)
{
notify();
}
The fact that thread 2 is able to wake up thread 1 means that thread 2 entered the synchronized block even though some other thread was in a synchronized block on the same object. That's fine with me but I'm wondering if that happens only for Object#wait() or for all methods that would make the thread "wait" (Thread#sleep, Thread#join). In my case I care about Thread#join because if the behavior is the same as Object#wait() it would break my code:
private void waitForClose()
{
try
{
// if one thread is waiting in join the other will wait on the semaphore
synchronized(joinLock)
{
if(outputThread != null && Thread.currentThread() != outputThread)
outputThread.join();
outputThread = null;
if(inputThread != null && Thread.currentThread() != inputThread)
inputThread.join();
inputThread = null;
}
}
catch(InterruptedException ex)
{
logger.error("Interrupted Exception while waiting for thread to join in " + name, ex);
}
}
So is it possible that multiple threads enter this synchronized block because of the join call putting the thread in a waiting state?
First of all the wait and notify mechanism is not really that funny. It is the most rudimentary way of coordinating two or more threads in Java. It is important to understand what is happening here:
Thread 1:
synchronized (someLock) {
System.out.println("Thread 1 going to wait ...");
someLock.wait();
System.out.println("Threads 1 got notified.");
}
Thread 2:
synchronized (someLock) {
System.out.println("Notifying");
someLock.notify();
System.out.println("Exiting block.");
}
The wait() call will relinquish the lock allowing another thread to take hold of it. At this point, thread 1 will not be able to proceed even if it gets notified. This documentation clearly states this:
The awakened thread will not be able to proceed until the current
thread relinquishes the lock on this object.
So it is only after thread 2 exits the synchronized block that thread 1 will proceed with the code after the wait().
Thread.join() is syntactic sugar, a helper method that underneath the hood makes use of the same wait and notify / notifyAll() methods. In fact the javadoc warns against using wait and notify on Thread objects, not to interfere with this mechanism.
This implementation uses a loop of this.wait calls conditioned on
this.isAlive. As a thread terminates the this.notifyAll method is
invoked. It is recommended that applications not use wait, notify, or
notifyAll on Thread instances.
Thread.sleep() is unrelated to wait and notify. It does not need an object's lock, and does not need to be in a synchronized block.
Your code seems to be synchronizing on an object called joinLock while the outputThread.join() will be synchronizing and waiting on the outputThread object. They are unrelated. If anything you might risk a dead lock if outputThread is synchronizing on joinLock. Without the code for the outputThread I can't say.
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.
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.
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
I have been playing around with implementing my own very basic semaphore and have noticed that the implementation I choose influences whether or not I get a deadlock. But I don't understand how the deadlock is happening.
My original implementation (no deadlock):
public synchronized void waitFor(){
value--;
if(value < 0)
wait();
}
public synchronized void signal(){
value++;
notify();
}
A later implementation (results in deadlock):
public synchronized void waitFor(){
value--;
while(value < 0)
wait();
}
public synchronized void signal(){
value++;
notifyAll();
}
The wait() is actually surrounded by a try-catch in both sets of code for catching thread interruptions, but I have left it out for readability and am assuming it makes no difference to the deadlock issue.
Anyone have any ideas?
I can't spot any deadlock risk with the second implementation. The while loop is the right choice for waiting on a lock (See spurious wakeups in Object.wait() documentation).
Also, it looks like no signal operation can be missed. A signal can only occur when another thread is in a wait state, or when no other thread is running waitFor().
Therefore, I suggest that you check other parts of the code:
Do all threads synchronize on the same instance of the semaphore?
Are you sure that the value counter isn't used elsewhere, in a
non-thread-safe manner?
Do all threads call sepmaphore.signal() when
they are done? (Typically this kind of release operations are placed in a finally block).
This is because a synchronized method actually locks the whole object. So that if one synchronized method of an object is called, all other synchronized methods of the same object will wait.
As you stay in your waitFor method until value becomes less than 0 and your signal method is waiting for the other sync method to complete, it deadlocked itself.
Try using getters and setters for your value and have them synchronize. That way only the actual access is synchronized and not the wait loop as well.
as you are using
while(value < 0)
wait();
in your latter implementation, it is within an non-ending loop for value <0 and it is looping here for ever.
This may be a pointer of your deadlock situation.