Given the following object defined and initialized in a wrapper class:
// (thread-safe) List of Requests made by users
private static List<Request> requests = Collections.synchronizedList(new ArrayList<Request>());
The following code is being called constantly in an update loop:
// <-- (Thread 1 executes the following code @ Runtime=1.0000000ms)
synchronized(requests) {
for (Request request : requests)
request.handle();
requests.clear();
}
And this also happens "simultaneously".
// (Thread 2 executes the following code also @ Runtime=1.0000000ms)
synchronized(requests) {
(requests.add(new Request());
}
It is my understanding that the following is guaranteed to happen in this situation: one of the threads will successfully lock the requests List, perform its respective task, and release its lock upon exiting the synchronous block.
Here is where things get weird for me in my understanding of "thread-safety". Let's say that Thread 1 has achieved its lock on the requests List and has entered its synchronous block first, despite Thread 2 attempting to do the same.
1) What happens to the code inside of a synchronous block that cannot be called due to the synchronicity of an object not being achieved? (In this case, with Thread 2 and the new Request() that this thread is attempting to add to the List - what happens to it? - does the request just poof and is never added to the requests List since Thread 1 has locked the object?
2) Is Thread 2 literally waiting for Thread 1 to release its lock and upon that happening Thread 2 gets a fresh look at the object and adds the request? (Hypothetical pitfall) If this is the case - what if Thread 1 takes 60 seconds to perform handle() on all of the Request objects in the List - causing Thread 2 to be waiting for those 60 seconds?
(bonus question) Do the answers for 1&2 with respect to Collections.synchronizedList follow the same behavior as ConcurrentHashMap?
Other thread will get blocked until the thread that has acquired has released the lock. After that the holding thread releases the lock any of the waiting threads can acquire it. The one which acquires the lock can proceed other will have to wait again.
Yes Thread 2 will have to wait till Thread 1 releases the lock. Only then it can acquire the lock.
Each lock has an associated monitor that governs who get access to the critical region the lock is associated with. At a time only one thread can acquire this monitor and can access the associated critical region. All other thread will have to wait to acquire the monitor.