我有两个组成部分:
add(Data)
的经理。这会向管理员添加一些数据。retrieve(predicate)
。返回与给定谓词匹配的Data
个对象的列表。如果没有此类数据,retrieve
会一直等待。此处不能使用典型的阻塞优先级队列,因为客户端对每个新对象都不感兴趣。只有那些被谓词中定义的要求所允许的人才对他有用。
如何在Java中实现?在每次调用管理器中的x.notifyAll()
和add(Data)
方法中的x.wait()
后,我都可以使用retrieve(predicates)
调用。我想知道java.concurrent
包是否具有更高级别的功能,可用于此问题。
答案 0 :(得分:1)
以下是可能会给您一个想法的概要。为简单起见,我假设by-name
和predicates
是字符串。
如你所说,你提前不知道你的data
所以我会尝试根据新的传入谓词动态更新和缓存。
<强>管理器强>
predicates
<强>客户端强>
public class Manager(){
private Map<String, Set<String>> jobs = new HashMap<>():
private Set<String> knownPredicates = new HasSet();
private final static String GENERAL = "GENERAL_DATA";
public void addJob(String data){
Set<String> matchingPredicates = getMatchingPredicates(data);
if(matchingPredicates.isEmpty()){
updateJobs(GENERAL, data);
} else {
for(String predicate: matchingPredicates){
updateJobs(GENERAL, data);
}
}
synchronized(this){
notifyAll();
}
}
private Set<String> getMatchingPredicates(String data){
Set<String> matchingPredicates = new HashSet<>();
for(String knownPredicate: knownPredicates){
// Check if the data matched the predicate. If so add it to the list
}
return matchingPredicates;
}
private void updateJobs(String predicate, String data){
Set<String> dataList;
if(jobs.containsKey(predicate)){
dataList = jobs.get(predicate);
} else {
dataList = new HashSet<>();
}
dataList.add(data);
jobs.put(predicate, dataList);
}
public synchronized List<String> retrieve(String predicate){
Set<String> jobsToReturn;
knownPredicates.add(predicate);
if(jobs.containsKey(predicate)){
jobsToReturn = jobs.remove(predicate);
}
for(String unknownData: jobs.get()){
//Check if unknownData matches the new predicate if it does add it to jobsToReturn
}
cleanupData(jobsToReturn);
return jobsToReturn;
}
//Removes data that may match more than one predicate
private static void cleanupData(Set<String> dataSet){
for(String data: dataSet){
for(Set <String> predicateSet: jobs.values()){
predicateSet.remove(data);
}
}
}
}
以上只是一个骨架。您必须解决有关清除已知谓词等问题。 。
答案 1 :(得分:-1)
您可能需要考虑使用以下行为实现基于谓词的缓存:
'retrieve(predicate)'
方法且执行了'add(Data)'
方法,则只需将新的Data对象添加到管理器中,缓存仍为空。'retrieve(predicate)'
方法,则客户端会检查缓存中是否有所请求的谓词,以便检索对相应Data对象的引用。如果缓存为空或未找到匹配项,系统将针对管理器中的所有Data对象运行指定谓词的搜索,并更新缓存。要提高性能,如果找不到匹配项,请在缓存中将其标记为高速,以便更快地返回对同一谓词的后续查询。'add(Data)'
方法并且缓存不为空,则扫描已添加的数据对象以查找缓存中已有的所有谓词,并且匹配对象通过引用与缓存中的相应谓词相关联。 请注意,作为任何缓存机制,它在开始时会较慢,但会随着更多对象填满缓存而改进。