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