问个java多线程加锁的问题
大家好,下面的代码定义于一个更大的类class Program内,且变量totalNumNodes, 数组stat[]以及Object对象lock和lock_2也都定义于更大类class Program中,我已经对共享变量totalNumNodes和数组stat[]进行了加锁处理,可为什么每次运行函数OutputStat()的结果还是不一样呢?谢谢大家!
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); }