• Post Reply Bookmark Topic Watch Topic
  • New Topic

Some clarification on lock, wait in a synch block of code - please help  RSS feed

 
Sathvathsan Sampath
Ranch Hand
Posts: 96
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello all,
when a wait() is invoked, the current thread relinquishes the lock on the object on which wait was invoked.
But what exactly happens with following scenario;

My question:
=============
1) When the current thread goes into wait on innerObject, it gives up the lock on it, and once again, when notified it
acquires the lock and continues.
But, what happens to the outerObject lock during this time ?? Does the lock on oject relinquished as well or still held.
Can someone please explain?
Many thanks in advance,
------------------
- Sathvathsan Sampath
 
Peter den Haan
author
Ranch Hand
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Sathvathsan Sampath:
But, what happens to the outerObject lock during this time ?? Does the lock on oject relinquished as well or still held.

It is still held. For that reason, the code you listed appears to be deadlock-prone -- if the event you are wait()ing for also attempts to acquire a lock on outerObject before calling innerObject.notify(), you have a deadlock.
- Peter
 
Sathvathsan Sampath
Ranch Hand
Posts: 96
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Peter,
Many thanks again for your reply.
In my situation, I can't think of avoiding the scenario I have coded.
But, I aim at preventing the deadlock as follows:
1) the actual event that innerObject is wait()ing does NOT lock the outerObject at all in the first place.
2) I follow the the resource ordering meaning, I always pick up follow the same for acuring multiple locks - Lock outerObject and then Lock innerObject.
Therefore, my answer is:
Though, the code appears deadlock prone, I don't think (hopefully ) it would get into deadlock
Whats your take on this?
Btw, FYI, what I am trying to do is implement a task scheduler that contains a taskQueue. This in turn contains a list of task objects.
The code above is actually a part of my removeTask(Task t) method.
Each task has 3 states - IN_PROGRESS, PENDING, FINISHED.
So, when a thread invokes removeTask() on a IN_PROGRESS task, the removeTask() blocks until the task goes into FINISHED or PENDING state (this is again set by another thread in run() method).
so, the code looks like


Thanks again,

------------------
- Sathvathsan Sampath
 
Peter den Haan
author
Ranch Hand
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Sathvathsan Sampath:
Whats your take on this?

It's fine, as long as you're aware of the dangers. One question though - what's notifyAll() doing in Task.waitForStatusChange()? Do you need to notifyAll when the waiting thread is interrupted?
Depending on how removeTask() is supposed to work, you might consider removing the Task from the queue first, then releasing the lock on TaskScheduler, and only then waiting for the status of a running Task to change. The main difference would be that if two threads would attempt to remove the same running Task, the TaskScheduler would return false to the second thread straightaway instead of waiting for the Task to finish. The advantage is that the TaskScheduler remains functional while you're waiting for the Task to finish. And, you never need more than a single lock
- Peter
 
Sathvathsan Sampath
Ranch Hand
Posts: 96
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Peter,
Thanks a million for your respones first of all. They instigate me to review what I do each time I get a response.
Unfortunately, I don't have ppl around here with whom I can hold a such a discussion besides this abs place !
So, my answers to your questions are:
1)
One question though - what's notifyAll() doing in Task.waitForStatusChange()? Do you need to notifyAll when
the waiting thread is interrupted?

My ans: Well, looking back at my code in class Task, I see that I can elimanate the waitForStatusChange(); instead in
the removeTask(task) method in the TaskScheduler class, I can do the following

2)
Depending on how removeTask() is supposed to work...... if two threads would attempt to remove the same
running Task, the TaskScheduler would return false to the second thread straightaway instead of waiting for the Task to
finish.

My Ans: The above scenario does not occur coz the algorithm I am using is:
Since, while wait()ing on task object, the lock of outer object i.e. taskQueue is not relienquished. Therefore, the 2nd
thread (coz of resource ordering mechanism), must first acquire the lock on the outer object taskQueue first, before it can
actually remove the task from taskQueue.
So, when a thread that was wait()ing is awakened coz of status change on inner task object, it immediately removes it from
the taskQueue and then relienques the lock and returns true.
Now the 2nd thread will now acquire lock on outer object and follow above steps, but would find the task already removed and
get false as return value. This is fine.

Btw, Peter, I should thank you again for your responses to my painfully long posts .
------------------
- Sathvathsan Sampath
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!