同步代码赏析
1 package com.test.multithreadDemo; 2 3 import java.io.*; 4 import java.util.Map; 5 import java.util.Random; 6 import java.util.concurrent.locks.Condition; 7 import java.util.concurrent.locks.Lock; 8 import java.util.concurrent.locks.ReentrantLock; 9 10 public class Test { 11 private static final int count = 10000; 12 private static final int threadGroupCount = 5; 13 private static final String inputFIle = "testInput.txt"; 14 15 private static void generateTestFile() throws IOException { 16 PrintWriter pw = new PrintWriter(new FileWriter(new File(inputFIle))); 17 Random random = new Random(); 18 for (int i = 0; i < count; i++){ 19 pw.write(Math.abs(random.nextInt()) % count + ","); 20 } 21 pw.flush(); 22 pw.close(); 23 } 24 25 public static void main(String [] args){ 26 try { 27 generateTestFile(); 28 BufferedReader reader = new BufferedReader(new FileReader(inputFIle)); 29 String str = reader.readLine(); 30 reader.close(); 31 String[] strs = str.split(","); 32 int index = 0; 33 int countForEachFile = count / threadGroupCount; 34 for (int i = 0; i < threadGroupCount; i++){ 35 int records[] = new int[countForEachFile]; 36 for (int j = 0; j < countForEachFile; j ++){ 37 records[j] = Integer.parseInt(strs[index]); 38 index++; 39 } 40 PrintGroup group = new PrintGroup(records, i); 41 ((PrintGroup) group).startPrint(); 42 } 43 }catch (Exception e){ 44 e.printStackTrace(); 45 } 46 } 47 48 static class PrintGroup{ 49 private static volatile int count = 0; 50 private Lock lock = new ReentrantLock(); 51 private Condition oddLock = lock.newCondition(); 52 private Condition evenLock = lock.newCondition(); 53 private int records[]; 54 private PrintWriter writer; 55 private volatile int oddIndex = 0; 56 private volatile int evenIndex = 0; 57 private OddPrintThread oddPrintThread; 58 private EvenPrintThread evenPrintThread; 59 private volatile boolean first = true; 60 private int[] result = new int[2000]; 61 private int index = 0; 62 63 public PrintGroup(int[] records, int id) throws Exception{ 64 this.records = records; 65 this.writer = new PrintWriter(new FileWriter(new File("output" + id + ".txt")), true); 66 } 67 68 public void startPrint(){ 69 oddPrintThread = new OddPrintThread(); 70 evenPrintThread = new EvenPrintThread(); 71 oddPrintThread.start(); 72 evenPrintThread.start(); 73 } 74 75 private class OddPrintThread extends Thread{ 76 @Override 77 public void run(){ 78 while (true){ 79 try { 80 lock.lock(); 81 if (first){ 82 first = false; 83 evenLock.await(); 84 } 85 for (int i = 0; i < 10; ){ 86 if (oddIndex >= records.length && evenIndex >= records.length){ 87 writer.flush(); 88 writer.close(); 89 return; 90 } 91 if (oddIndex >= records.length){ 92 break; 93 } 94 if (records[oddIndex] % 2 == 1 ) { 95 i++; 96 writer.print(records[oddIndex] + " "); 97 result[index++] = records[oddIndex]; 98 writer.flush(); 99 addCount(); 100 } 101 oddIndex++; 102 } 103 oddLock.signal(); 104 evenLock.await(); 105 } catch (Exception e ){ 106 e.printStackTrace(); 107 } finally { 108 oddLock.signal(); 109 lock.unlock(); 110 } 111 } 112 } 113 } 114 115 private class EvenPrintThread extends Thread{ 116 @Override 117 public void run(){ 118 while (true){ 119 try { 120 while (first){ 121 Thread.sleep(1); 122 } 123 lock.lock(); 124 for (int i = 0; i < 10;){ 125 if (oddIndex >= records.length && evenIndex >= records.length){ 126 String s = ""; 127 for (int k = 0; k < 2000; k++){ 128 s += (result[k] + ""); 129 } 130 writer.flush(); 131 return; 132 } 133 if (evenIndex >= records.length){ 134 break; 135 } 136 if (records[evenIndex] % 2 == 0){ 137 i++; 138 writer.print(records[evenIndex] + " "); 139 result[index++] = records[evenIndex]; 140 writer.flush(); 141 addCount(); 142 } 143 evenIndex++; 144 } 145 evenLock.signal(); 146 oddLock.await(); 147 } catch (Exception e){ 148 e.printStackTrace(); 149 } finally { 150 evenLock.signal(); 151 lock.unlock(); 152 } 153 } 154 } 155 } 156 private synchronized static void addCount(){ 157 count++; 158 if (count % 1000 == 0){ 159 System.out.println("已完成: " + count); 160 if (count == 10000){ 161 System.out.println("Done"); 162 } 163 } 164 } 165 } 166 }