0
votes

I am Looping through a Map , and i have a number of threads. the queue in the map contains Actions. my goal is to give every thread an Action to do.. but no 2 threads(or more) can run 2 task(or more) from one queue it means every thread is gonna search for a queue , and Lock the Queue some how and check if the queue has actions if yes it runs one of them if no search for another Queue to run fro them actions. NOTE: number of Queues can be greater than Number of Threads e I tried to synchronize on the 'Map.Entry'

        public void run() {

            while (true) {
                Action<?> act;
                for (Map.Entry entry :ActionMap.entrySet()) {
                   Synchronized(entry)
                   {
                      act =  ((Queue<Action>)entry.getValue()).poll();
                      if (act == null)
                        break;
                   }
                }

            }
            }  

the problem is that if another thread is searching for an action to do is gonna be stuck in the synchronized Line And Wait for the first thread to finish the task or to finish waiting and that is not what i want. i want all of the threads to search for queues if some a thread reaches a queue that another thread is working on just skip it and continue searching

so I digged around and found semaphore so I reached this

Semaphore Gate = new Semaphore(1);



        public void run() {

            while (true) {
                Action<?> act;
                for (Map.Entry entry :ActionMap.entrySet()) {
                   if( Gate.tryAcquire());
                   {
                      act =  ((Queue<Action>)entry.getValue()).poll();
                      if (act == null){
                    Gate.Release();
                    break;

                      }
                      else {
                      act.handle();
                      Gate.Release();
                    }
                   }
                }

            }
            }

put the problem with this that Gate.aquire() is gonna Lock all entries it means for 2 diffirent entries and 2 different threads only one thread can access the gate and execute the Action

so finally dose any one have a design pattern that can help me ? thank you ...

1
This sounds like an XY problem. What if you had just one thread that scans the map, and submits tasks to a thread pool? - Solomon Slow
i feel I was not clear in the explaination i gave two thoughts and said that they don't give me what i want ... i did that to clearify my problem.. I am not waiting for any one to tell me how to modify my code. other than that your solution wont help i have entries each entry contains queue in this queue there is an actions the threads job is to find entries(Queues) and execute actions ..with some constrains to know about them u can read above.. - Baraa Natour
I found a solution for it after all ..its to modify semaphore... a combination between semaphore and "syncronized"........thank you any way - Baraa Natour

1 Answers

1
votes

You could use java.util.concurrent types of map for this. They are thread safe, so you dont need Syncronize.

Synchronize means : the resource(which is synchronized) can't be modified by multiple threads simultaneously. e.g MAP returned by Collections.synchronizedMap(Map) will be a synchronized map and can be modified by one thread at a time, but Concurrent Collections allows multiple threads to access different parts of a collection at a given time, based on the requirement. e.g we have an overloaded constructor for ConcurentHashMap which takes input concurrencyLevel as number of threads which can access the collection simultaneously.