2014-10-01 62 views
0

我在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 

该数据会从上面的页面名作为关键字存储在HashMapDeque与访问该小时数每小时更新一次。

我想要有一个线程ThreadRead,它读取输入文件并将信息存储在HashMap中。然后一个ThreadCompute线程为HashMap中的每个密钥消耗关联的Deque

ThreadRead需要锁定所有ThreadComputes,同时处于激活状态,然后在完成后将其唤醒,以便ThreadComputes可以同时工作。

如果我需要为每个ThreadCompute使用不同的互斥锁,那么我怎样才能让所有锁定在ThreadRead之间?完成后我怎样才能从ThreadRead中唤醒所有的ThreadComputes

我已经使用info作为锁ThreadReadinfo.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

我认为最简单的(低级别)方法是使用'Object'作为锁和'wait' /'notifyAll'机制。但是有很多更高层次的方法可以做到这一点。你应该发布一些代码。 – Mena 2014-10-01 16:26:03

+1

是的,如果您发布所需的最少代码来重现此问题,则您更有可能获得更具体的帮助。 [这个问题](http://stackoverflow.com/questions/10946565/java-thread-synchronization-thread-sleep-method-not-working-as-desired)是一个很好的例子。 – 2014-10-01 16:30:38

+0

时间到了。投票结束... – Mena 2014-10-01 16:37:59

回答

2

java.util.concurrent.locks.ReentrantReadWriteLock类对这类问题很好。应该有一个实例来保护整个HashMap。文件读取器需要获取编写锁的ReadWriteLock,因为它想修改映射。其他线程需要各自获取自己的读取锁定从一个ReadWriteLock

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