我創建了一個簡單的搜索引擎:併發管理在Java中
public String search(Map<String, Object> params) {
String result = /*search*/;
return result;
}
此方法執行搜索過程並返回結果(JSON),但有一個很大的問題...... 因爲搜索過程是昂貴的,如果一些用戶同時使用相同的關鍵字執行搜索過程,搜索過程將分別爲每個執行!
我有兩個選擇,以避免這種情況:
1:
private static final ConcurrentHashMap<Object, ConcurrentLinkedQueue<Locker<Object, String>>> CONCURRENT_SEARCHES = new ConcurrentHashMap<>();
public String search(Map<String, Object> params) {
Object key = params.get("keyword");
assert key != null;
ConcurrentLinkedQueue<Locker<Object, String>> queue = CONCURRENT_SEARCHES.get(key);
if (queue != null) {
System.out.println("waiting");
Locker<Object, String> locker = new Locker<>(key);
queue.add(locker);
locker.lock();
String result = locker.getValue();
return result == null ? "[]" : result;
}
System.out.println("new search");
CONCURRENT_SEARCHES.put(key, (queue = new ConcurrentLinkedQueue<>()));
String result = /*search*/;
CONCURRENT_SEARCHES.remove(key);
Locker<Object, String> locker;
while ((locker = queue.poll()) != null) {
locker.setValue(result);
locker.unlock();
}
return result;
}
:如你所知,這不會使用共享對象恰好解決這個問題...
2-
這工作真的很好,但又有一個小問題。
測試:
public static void main(String[] args) {
String id = "1";
ProcessSession session = ProcessManager.openSession(id);
//...
ExecutorService service = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
service.submit(() -> session.search("keyword"));
}
}
輸出:
new search
waiting
waiting
new search
waiting
waiting
waiting
waiting
waiting
waiting
編輯:
public final class Locker<K, V> {
private final Object o = new Object();
private final K key;
private V value;
public Locker(K key) {
this.key = key;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
public void lock() {
synchronized (o) {
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void lock(long timeout) {
synchronized (o) {
try {
o.wait(timeout);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void unlock() {
synchronized (o) {
o.notify();
}
}
}
這是怎麼回事錯在這裏?任何人都可以提出一個更好的解
謝謝。
那麼,您緩存搜索,而不是搜索結果。因此,如果沒有正在進行的關鍵字搜索,即使之前進行了類似的搜索,也會啓動新的關鍵字。 – kiheru 2014-12-02 11:39:43
搜索結果不固定,可能由於某些原因而稍後更改... – FaNaJ 2014-12-02 11:42:49
那麼測試運行時會出現什麼問題?大多數搜索與以前的搜索結合在一起。這不是你想要做的嗎? – kiheru 2014-12-02 11:48:16