我正在用Java写一个程序,我有一个HashMap<String, Deque<Integer>> info;
我的数据是按小时时间段访问的维基百科页面列表,以及每次访问次数的计数。
de Florian_David_Fitz 18
de G%C3%BCnther_Jauch 1
de Gangs_of_New_York 2
de Georg_VI._(Vereinigtes_K%C3%B6nigreich) 7
de Gerry_Rafferty 2
此数据会从上方存储在HashMap
中,页面名称为关键字,Deque
每小时更新一次,以及当时的访问次数。
我希望有一个线程ThreadRead
读取输入文件并将信息存储在HashMap
中。然后ThreadCompute
中每个使用相关HashMap
消息的Deque
个帖子{/ 1}}。
ThreadRead
需要在激活时锁定所有ThreadComputes
,然后在完成时将其唤醒,以便ThreadComputes
可以同时工作。
如果我需要为每个ThreadCompute
使用不同的互斥锁,那么在ThreadRead
工作时如何锁定所有互斥锁?我怎样才能在完成后从ThreadComputes
唤醒所有ThreadRead
?
我使用info
作为ThreadRead
的锁定,info.get(key)
使用每个ThreadCompute
但是它没有按预期工作。
编辑:
我添加了一些代码以尝试更清楚地解决问题。这就是我现在所拥有的:
HashMap<String, Deque<Integer>> info;
boolean controlCompute, control Read;
private static class ThreadRead extends Thread {
public void run() {
while(controlRead) {
try {
read();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void read() throws InterruptedException{
synchronized(info){
while(count==numThreads){
for (File file: files){
reader.parse(file, info); // Reads the file and store the data in the Hashmap
keys=true;
while(info.getSizeDeque()>10){
count=0;
info.wait();
info.notifyAll();
}
}
}
controlRead=false;
}
}
}
private static class ThreadCompute extends Thread {
public String key;
public void run() {
while(controlCompute) {
try {
compute();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void compute() throws InterruptedException{
synchronized(info.get(key)){
if(count!=numThreads){
algorithms(); //Here I apply the algorithms to the integers in the deque
if(controlRead){
info.get(key).removeFirst();
count++;
if(count==numThreads){
info.notify();
info.get(key).wait();
}
info.get(key).wait();
}
if(info.isEmptyDeque(key)){
controlCompute=false;
}
}
}
}
}
答案 0 :(得分:2)
班级java.util.concurrent.locks.ReentrantReadWriteLock
适用于此类问题。应该只有一个实例来保护整个HashMap
。文件阅读器需要获取ReadWriteLock
的 write 锁,因为它想要修改地图。其他线程需要从ReadWriteLock
获取自己的读取锁。
所有线程必须小心尽可能地限制它们持有锁的范围,因此特别是,文件读取线程应该在修改映射之前立即获取写锁,保持它直到所有修改为一个条目完成,然后释放它。其他线程不会相互阻塞,因此原则上它们可以更长时间地保持锁定,但这样做会阻止文件读取器。