![](/img/trans.png)
[英]java thread waiting for input on comport blocks other thread as well
[英]Java concurrency - pass data to other waiting thread
我有两个组成部分:
add(Data)
的管理器。 这会将一些数据添加到管理器。 retrieve(predicate)
。 返回与给定谓词匹配的Data
对象的列表。 如果没有此类数据,则retrieve
将继续等待。 由于客户端对每个新对象都不感兴趣,因此无法在此处使用典型的阻塞优先级队列。 只有那些由谓词中定义的他的要求所允许的人才对他有用。
如何用Java实现呢? 我能得到它工作x.notifyAll()
在每次通话后调用add(Data)
的经理,和x.wait()
在retrieve(predicates)
方法。 我想知道java.concurrent
包是否具有可以用于此问题的更高级功能。
以下是一些可能会给您带来想法的概述。 为了简单起见,我将假定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);
}
}
}
}
客户
public class Client() implements Runnable{
private Manager managerRef;
public Client(Manager m){
managerRef = m;
}
public void run() {
while(true){
String predicate = //Get the predicate somehow
Set<String> workToDo = managerRef.retrieve(predicate)
if(workToDo.isEmpty()){
synchornized(managerRef){
managerRef.wait();
}
} else {
//Do something
}
}
}
}
上面只是一个骨架。 您将必须解决一些有关清除已知谓词等的问题。 。
您可能需要考虑使用以下行为来实现基于谓词的缓存:
'retrieve(predicate)'
方法并且执行了'add(Data)'
方法, 'add(Data)'
一个新的Data对象简单地添加到管理器中,并且缓存保持为空。 'retrieve(predicate)'
方法,则客户端将在高速缓存中检查所请求的谓词,以便检索对相应Data对象的引用。 如果高速缓存为空或找不到匹配项,则系统针对管理器中的所有数据对象在指定谓词上进行搜索,并更新高速缓存。 为了提高性能,如果找不到匹配项,请在缓存中将其标记出来,以便更快地返回对同一谓词的后续查询。 'add(Data)'
方法并且缓存不为空,则将对要添加的Data对象进行扫描,以查找缓存中已经存在的所有谓词,并且匹配对象将通过引用与缓存中的相应谓词相关联。 请注意,任何缓存机制在开始时都会比较慢,但随着更多对象填满缓存,它会有所改善。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.