0

I have a blocking queue which consists of my thread objects. For me the order in which these threads were formed is important. Also each thread is associated with a key. So wht I wanted to do was, if a thread for a key is running then all other threads on the key should be blocked. But when the thread finishes its execution, the thread with same key in the queue but oldest should be notified and executed. So I was planing to make a blocking queue of hashmap where in hashmap, my key is key and value is my thread object. My problem is 1. HOw do I search for thread related to a particular key in my queue. 2. How do I notify that thread to execute now.

dtyagi
  • 11
  • 3
  • How about you create the blocking queue of your Key objects instead of `Thread objects`. Each entry in the blocking queue is a `List`. Now if multiple threads want to process that Key and if its in the BlockingQueue, you simply append to the List. That way the processing of each Key is in the order in which the thread gets scheduled for it. As soon as one thread for that Key is done, you can start with next one(no need to notify or block since now only one thread is processing one key at a time). Hope that makes sense – Neo Apr 04 '15 at 07:35
  • Hey.Thanks for reply. Could you provide a sample code sorts..... – dtyagi Apr 04 '15 at 15:33

1 Answers1

0

Here is what I was talking about. This should give you enough clues. This is not tested and doesn't take care of synchronization that you might need depending on you use-case.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

// E - Element of type key.
public class Design1<E> {

  private BlockingQueue<List<MyThread<E>>> myQueue;

  // Provides a quicker lookup for the threads for a certain key instead of checking all elements in Queue.
  private Map<E, List<MyThread<E>>> myKeyMap;

  public Design1() {
    // Initialize both myQueue and myKeyMap here.
    myQueue = new ArrayBlockingQueue<>(100);
    myKeyMap = new HashMap<>();
  }

  class MyThread<K> extends Thread {
    K key;

    public K getKey() {
      return key;
    }
    public void run() {
      // Process the key

    }
  }

  public void addToQueue(E key) {
    List<MyThread<E>> keyThreads = myKeyMap.get(key);
    if (keyThreads == null) {
      keyThreads = new ArrayList<>();
    }

    // Create new thread for this key
    MyThread<E> t = new MyThread<E>();
    keyThreads.add(t);

    myKeyMap.put(key, keyThreads);

    try {
      // Block if full.
      myQueue.put(keyThreads);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  public void processQueue(E key) {
    try {
      while (true) {
        // Fetch elems from Queue - block if empty
        List<MyThread<E>> keyThreads =  myQueue.take();
        E myKey = null;
        while (keyThreads.size() > 0) {
          // Process all the threads for the same key
          MyThread<E> thread = keyThreads.remove(0);
          myKey = thread.getKey();
          thread.start();
        }
        if (myKey != null) {
          // Clean up hashmap entry too.
          myKeyMap.remove(myKey);
        }
      }
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}
Neo
  • 4,640
  • 5
  • 39
  • 53