File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Threads and Synchronization and the fly likes Priority Semaphore/Lock Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Priority Semaphore/Lock" Watch "Priority Semaphore/Lock" New topic
Author

Priority Semaphore/Lock

Michael Golightly
Greenhorn

Joined: Feb 01, 2011
Posts: 27
I have a situation where I have multiple threads running. One of them is a consumer of a shared data map, while the others are producing into the map. Because the producers will be putting more than one item into the map at a time, I need each of the threads to behave essentially in an atomic way. I can accomplish this by synchronizing the shared map, but it presents another problem. The consumer thread will be sleeping for some number of seconds, then waking up, taking everything off the map and pushing that data elsewhere. When the consumer thread wakes up, I want it to take priority over the data map so that if any of the producers are waiting to take control using the synchronized block (while another producer is processing), the consumer runs before they do. Essentially what I am looking for is some sort of priority semaphore or locking mechanism that will allow the consumer to be next in the list to use the data map. I'm looking into the java.util.concurrent package, but nothing is jumping out at me yet. I'll continue to research, but figured I'd ask the experts too.

Edit: I should mention that I'm not partial to semaphores, it can be any implementation.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 19061
    
  40

Michael Golightly wrote:I have a situation where I have multiple threads running. One of them is a consumer of a shared data map, while the others are producing into the map. Because the producers will be putting more than one item into the map at a time, I need each of the threads to behave essentially in an atomic way. I can accomplish this by synchronizing the shared map, but it presents another problem. The consumer thread will be sleeping for some number of seconds, then waking up, taking everything off the map and pushing that data elsewhere. When the consumer thread wakes up, I want it to take priority over the data map so that if any of the producers are waiting to take control using the synchronized block (while another producer is processing), the consumer runs before they do. Essentially what I am looking for is some sort of priority semaphore or locking mechanism that will allow the consumer to be next in the list to use the data map. I'm looking into the java.util.concurrent package, but nothing is jumping out at me yet. I'll continue to research, but figured I'd ask the experts too.

Edit: I should mention that I'm not partial to semaphores, it can be any implementation.



I don't think priority is supported, by either the Lock (ReentrantLock) or Semaphore class. The best you can do is to have fairness enabled. This will guaranteed that no lock grab "skips the line", and hence, make sure that the consumer thread doesn't starve from the producers.


Now, in thinking about it a bit more, you can simulate what you want easily by using two locks. Have the producer grab lock A, then lock B, before processing. The second lock (lock B) should be an uncontended lock grab since all the producers should be blocked on A. Later, when the one consumers wants the lock, it simply grabs Lock B (it skips grabbing A). Since the consumer is the only thread waiting for lock B, because the other producers are on Lock A, it will get it as soon as the currently running producer releases it. As for the next producer, it will wait on Lock B, until the consumer releases it.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Michael Golightly
Greenhorn

Joined: Feb 01, 2011
Posts: 27
Henry Wong wrote:
Michael Golightly wrote:I have a situation where I have multiple threads running. One of them is a consumer of a shared data map, while the others are producing into the map. Because the producers will be putting more than one item into the map at a time, I need each of the threads to behave essentially in an atomic way. I can accomplish this by synchronizing the shared map, but it presents another problem. The consumer thread will be sleeping for some number of seconds, then waking up, taking everything off the map and pushing that data elsewhere. When the consumer thread wakes up, I want it to take priority over the data map so that if any of the producers are waiting to take control using the synchronized block (while another producer is processing), the consumer runs before they do. Essentially what I am looking for is some sort of priority semaphore or locking mechanism that will allow the consumer to be next in the list to use the data map. I'm looking into the java.util.concurrent package, but nothing is jumping out at me yet. I'll continue to research, but figured I'd ask the experts too.

Edit: I should mention that I'm not partial to semaphores, it can be any implementation.



I don't think priority is supported, by either the Lock (ReentrantLock) or Semaphore class. The best you can do is to have fairness enabled. This will guaranteed that no lock grab "skips the line", and hence, make sure that the consumer thread doesn't starve from the producers.


Now, in thinking about it a bit more, you can simulate what you want easily by using two locks. Have the producer grab lock A, then lock B, before processing. The second lock (lock B) should be an uncontended lock grab since all the producers should be blocked on A. Later, when the one consumers wants the lock, it simply grabs Lock B (it skips grabbing A). Since the consumer is the only thread waiting for lock B, because the other producers are on Lock A, it will get it as soon as the currently running producer releases it. As for the next producer, it will wait on Lock B, until the consumer releases it.

Henry


I like love that idea. Does it not have the problem of the producer holding lock A and B releasing A and B and a second producer grabbing A and B before the consumer is awakened to grab B? Even if this is possible, the chance seems to be remarkably low.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 19061
    
  40

Michael Golightly wrote:
Henry Wong wrote:Now, in thinking about it a bit more, you can simulate what you want easily by using two locks. Have the producer grab lock A, then lock B, before processing. The second lock (lock B) should be an uncontended lock grab since all the producers should be blocked on A. Later, when the one consumers wants the lock, it simply grabs Lock B (it skips grabbing A). Since the consumer is the only thread waiting for lock B, because the other producers are on Lock A, it will get it as soon as the currently running producer releases it. As for the next producer, it will wait on Lock B, until the consumer releases it.


I like love that idea. Does it not have the problem of the producer holding lock A and B releasing A and B and a second producer grabbing A and B before the consumer is awakened to grab B? Even if this is possible, the chance seems to be remarkably low.



If Lock B is configured to be fair. This case will be impossible. The thread that requests Lock B first will get it -- it will be impossible for a producer to get Lock A and then Lock B, with a consumer already waiting on Lock B.

Henry
Michael Golightly
Greenhorn

Joined: Feb 01, 2011
Posts: 27
Henry Wong wrote:
Michael Golightly wrote:
Henry Wong wrote:Now, in thinking about it a bit more, you can simulate what you want easily by using two locks. Have the producer grab lock A, then lock B, before processing. The second lock (lock B) should be an uncontended lock grab since all the producers should be blocked on A. Later, when the one consumers wants the lock, it simply grabs Lock B (it skips grabbing A). Since the consumer is the only thread waiting for lock B, because the other producers are on Lock A, it will get it as soon as the currently running producer releases it. As for the next producer, it will wait on Lock B, until the consumer releases it.


I like love that idea. Does it not have the problem of the producer holding lock A and B releasing A and B and a second producer grabbing A and B before the consumer is awakened to grab B? Even if this is possible, the chance seems to be remarkably low.



If Lock B is configured to be fair. This case will be impossible. The thread that requests Lock B first will get it -- it will be impossible for a producer to get Lock A and then Lock B, with a consumer already waiting on Lock B.

Henry

Excellent, I'm running a test on it now to make sure it behaves the way I want it to.
Michael Golightly
Greenhorn

Joined: Feb 01, 2011
Posts: 27
This appears to be working. Can you see any glaring problems?

Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 19061
    
  40

Michael Golightly wrote:This appears to be working. Can you see any glaring problems?


Looks fine. The only issue that I can think of is that this is a simple lock -- meaning no support of condition variables. If this is what you need, then great.

Henry
Michael Golightly
Greenhorn

Joined: Feb 01, 2011
Posts: 27
Henry Wong wrote:
Michael Golightly wrote:This appears to be working. Can you see any glaring problems?


Looks fine. The only issue that I can think of is that this is a simple lock -- meaning no support of condition variables. If this is what you need, then great.

Henry

For what I need it for, this works. It's a simple lock without any fancy bells and whistles.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Priority Semaphore/Lock