阻塞队列+线程+线程执行顺序

时间:2015-04-04 06:49:06

标签: java multithreading hashmap blockingqueue

我有一个阻塞队列,它由我的线程对象组成。对我来说,形成这些线程的顺序很重要。每个线程也与一个键相关联。所以我想做的是,如果一个密钥的线程正在运行,那么密钥上的所有其他线程都应该被阻止。但是当线程完成其执行时,应该通知并执行队列中具有相同键但最早的线程。所以我计划在hashmap中创建一个hashmap的阻塞队列,其中key是key,value是我的线程对象。我的问题是1.我是否要搜索与队列中特定密钥相关的线程。 2.如何通知该线程立即执行。

1 个答案:

答案 0 :(得分:0)

这就是我所说的。这应该给你足够的线索。这未经过测试,并且根据您的使用情况不会处理您可能需要的同步。

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();
    }
  }
}