日期:2014-05-20  浏览次数:21163 次

问个java多线程加锁的问题
大家好,下面的代码定义于一个更大的类class Program内,且变量totalNumNodes, 数组stat[]以及Object对象lock和lock_2也都定义于更大类class Program中,我已经对共享变量totalNumNodes和数组stat[]进行了加锁处理,可为什么每次运行函数OutputStat()的结果还是不一样呢?谢谢大家!
Java code
    
    
    public class MyThread extends Thread{
        private CountDownLatch threadsSignal;
        private int hsmapCapacity;
        private long forAndVal;
        private boolean DNAFormat;
        private long forAndVal32;
        
        public MyThread(CountDownLatch threadsSignal, int capacity, boolean DNAFormat){
            super();
            this.threadsSignal = threadsSignal; 
            this.hsmapCapacity = capacity;
            this.forAndVal = (long)Math.pow(2, 2*(k-32)) - 1;
            this.DNAFormat = DNAFormat;
            this.forAndVal32 = (long)Math.pow(2, 2*k) - 1;
        }
        
        @Override
        public void run(){
            System.out.println(Thread.currentThread().getName() + "Start..."); 
            
            FileReader fr;
            BufferedReader bfr;
            FileWriter fw = null;
            BufferedWriter bfw = null;
            DataOutputStream out = null;
            HashMap<Kmer,Integer> nodes = new HashMap<Kmer,Integer>(hsmapCapacity);
            
            String line;
            
            Random rd = new Random();
            int p,j;
            Kmer k1, k1_rev;
            
            
            try{
                File dir = new File("Maps(count)");
                if(!dir.exists())
                    dir.mkdir();
                
                nodes.clear();
                
                while(blocks.cardinality()<numOfBlocks){
                    
                    p = rd.nextInt(numOfBlocks);
                    
                    while(blocks.get(p)==true)
                        p = rd.nextInt(numOfBlocks);
                    
                    blocks.set(p);
                    
                    fr = new FileReader("Nodes/nodes"+p);
                    bfr = new BufferedReader(fr, bufSize);
                    if(DNAFormat){                    
                        fw = new FileWriter("Maps(count)/maps"+p);
                        bfw = new BufferedWriter(fw, bufSize);
                    }
                    else{
                        out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(new File("Maps(count)/maps"+p)), bufSize));
                    }
                    while((line = bfr.readLine()) != null){                    
                        
                        
                        for(j = 0; j < line.length() - k + 1; j++){
                
                            k1 = new Kmer(line.substring(j,k+j),false);
                        k1_rev = new Kmer(line.substring(j,k+j),true);
                            
                            if(!nodes.containsKey(k1) && !nodes.containsKey(k1_rev)){
                                nodes.put(k1, 1);                            
                            }
                            else if(nodes.containsKey(k1)){
                                nodes.put(k1, nodes.get(k1)+1);
                            }
                            else if(nodes.containsKey(k1_rev)){
                                nodes.put(k1_rev, nodes.get(k1_rev)+1);
                            }    
                            
                        }
                    }
                    
                    Iterator<Entry<Kmer, Integer>> iter = nodes.entrySet().iterator(); 
                    while (iter.hasNext()) { 
                         Entry<Kmer, Integer> entry = (Entry<Kmer, Integer>) iter.next();  
                         
                         if(!DNAFormat){
                             if(k > 32)
                                 out.writeLong(entry.getKey().high);
                             out.writeLong(entry.getKey().low);
                             out.writeInt(entry.getValue());
                         }
                         else{
                             bfw.write(entry.getKey().toDNA(k)+"\t"+entry.getValue()+"\n");
                         }
                         
                         synchronized(lock){
                             stat[entry.getValue()]++;
                         }
                    }
                    
                    synchronized(lock_2){
                        totalNumNodes+=nodes.size();
                    }
                    
                    nodes.clear();
                    
                    if(DNAFormat)
                    {
                        bfw.close();
                        fw.close();
                    }
                    else
                        out.close();
                        
                    bfr.close();
                    fr.close();    
                    
                }
                            
            }catch(Exception E){
                System.out.println("Exception caught!");
                E.printStackTrace();
            }
            
            threadsSignal.countDown();  
            System.out.println(Thread.currentThread().getName() + "End. Remaining" + threadsSignal.getCount() + " threads");  
            
        }
    }
    
    private void BuildMap(int threadNum, int hsmapCapacity, boolean DNAFormat) throws Exception{
        CountDownLatch threadSignal = new CountDownLatch(threadNum);
        
        for(int i=0;i<threadNum;i++){
            Thread t = new MyThread(threadSignal, hsmapCapacity, DNAFormat);
            t.start();
        }
        threadSignal.await();
        System.out.println(Thread.currentThread().getName() + "End."); 
    }

        private void OutputStat() throws Exception{
        for(int i=1;i<=5000000;i++){
            if(stat[i]!=0){
                bfw_stat.write(i+"\t"+stat[i]+"\n");
            }
        }
        bfw_stat.close();
        fw_stat.close();
        
        System.out.println("Total num of nodes: "+totalNumNodes*2);
    }