同步一组线程

时间:2014-10-01 16:22:21

标签: java multithreading mutex

我正在用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;
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:2)

班级java.util.concurrent.locks.ReentrantReadWriteLock适用于此类问题。应该只有一个实例来保护整个HashMap。文件阅读器需要获取ReadWriteLock write 锁,因为它想要修改地图。其他线程需要从ReadWriteLock获取自己的读取锁。

所有线程必须小心尽可能地限制它们持有锁的范围,因此特别是,文件读取线程应该在修改映射之前立即获取写锁,保持它直到所有修改为一个条目完成,然后释放它。其他线程不会相互阻塞,因此原则上它们可以更长时间地保持锁定,但这样做会阻止文件读取器。