Reputation: 514
I have a problem in a high performance environment which can be described in prose as follows:
I have an external Java API which makes a call to an FPGA card with 64 resources on it. I need a mechanism to safely share a subset of those resources between hundreds of threads in an application. Each resource should be considered not thread safe.
So I need a ResourcePool with a method update() which then calls resource.update().
I think this is a fairly common idiom but I am having difficulty fitting my head into the Java concepts. I want to say have 4 of the resources in one ResourcePool. Each should i guess live in their own Thread (so a threadpool would be needed).
How would i implement this so that i could log an error and carry on when all 4 of the resources are in use?
Hope this makes sense!
Upvotes: 0
Views: 843
Reputation: 200168
Since you basically have something that can be treated as a finite number of generic resources, you can apply any generic resource pooling library. Google returned pool4j as a first hit, this could be all you need. It is based on java.util.Stack
. Or you can roll your own solution.
Upvotes: 0
Reputation: 26
For the BlockingQueue, it very userful for the producer-consumer pattern, you must renew or add it after this resource by userd, but maybe the initialization of resource is poor perfomance. And it`s a blocking queue, if you want to deal some information when the pool is empty or full, Queue is ok for this.
For the lock, if these resources was initialized and not change after, add lock to these resources is better.
This is my opinion.
Upvotes: 1
Reputation: 24867
Using a LinkedBlockingQueue to pool resources, as suggested by @Peter, is fine as long as each thread only required one resource. If a number of threads need more than one of them, there can be a problem in the simple case when a number of threads have acquired some resources, but not enough for any of them to proceed - deadlock.
You could use two queues protected by one lock. One 'pool' queue of resource instances, one 'waiting' queue of thread instances waiting to acquire resources. A method of the thread class/s returns the number of resources it's currently waiting for.
Any thread that requires resources acquires the lock and checks the pool queue count first. If there are enough resources, it dequeues them and exits the lock. If there are not enough, it enqueues itself on the wait queue, exits the lock and waits..
Any thread that can release its resources acquires the lock. If the wait queue is empty, it releases the resources back to the pool, releases the lock and exits. If the wait queue is not empty, it iterates it, building a set of waiting threads that can be made ready with the sum of the resources waiting to be released and those remaining in the pool. It then applies some sort of algorithm to decide which waiting thread/s can be made ready. If there is none, it just releases the resources back to the pool and exits the lock. If there is one, it loads those thread/s up with the resources, notifies it/them, releases the lock and exits.
Upvotes: 2
Reputation: 533540
I would place an object representing each resource into a LinkedBlockingQueue.
To acquire a resource you can poll(), remove() or take() as you prefer.
To return a resource you can add it.
Upvotes: 3