疑似Google多线程面试题的Java实现 (二)

2014-11-24 07:29:04 · 作者: · 浏览: 2
rity(); // 调整outList中各MockOutput实例的顺序
81.
82. return true;
83. }
84. }
85. }
86. return false;
87. }
88.
89. public void cleanAndDisplay() {
90. working = false;
91. synchronized (outList) {
92. for (int i = 0; i < FILE_NAMES.length; i++) {
93. MockOutput out = outList.get(i);
94. out.close();
95.
96. System.out.println(out.toString());
97. }
98. }
99. }
100.
101. /**
102. * 初始化每个MockOutput实例的最后一次写入值,并把其加入到outList中
103. * @throws IOException
104. */
105. private void init() throws IOException {
106. for (int i = 0; i < FILE_NAMES.length; i++) {
107. MockOutput output = new MockOutput(64, FILE_NAMES[i], FILE_PATH);
108. output.setTheLatestNum(i);
109. outList.add(output);
110. }
111. }
112.
113. /**
114. * 使用Comparator的自身实现对outList内的对象进行排序,其作用在于平衡写入优先级.
115. * 例如:线程Thread-2取得了outList对象的锁执行写入,其绑定的值为3,而outList中
116. * 有两个MockOutput实例的最后一次写入都为2,均满足再次写入的条件.但是其中一个的长度
117. * 远远大于另一个,并且其在outList内的位置又在另一个之前,则其将先于后者获得再次写
118. * 入得机会,使得两者的机会不均衡.
119. * 此方法的作用就在于把写入机会少的MockOutput调整到最前面从而提高其被写入的机会.
120. */
121. private void adjustPriority() {
122. Collections.sort(outList, comparator);
123. }
124.
125. private class WriteWorker extends Thread {
126.
127. /** 多个线程共享同一个MultiThreadWriter实例 */
128. private MultiThreadWriter writer;
129.
130. /** 线程绑定的写入值,每个线程只反复写入一个固定值 */
131. private final int num;
132.
133. private final CountDownLatch start;
134. private final CountDownLatch end;
135.
136. public WriteWorker(MultiThreadWriter writer, int num, CountDownLatch start, CountDownLatch end) {
137. this.writer = writer;
138. this.num = num;
139. this.start = start;
140. this.end = end;
141. }
142.
143. public void run() {
144. try {
145. start.await();// 等待主线程一声令下,所有的子线程均唤醒开始工作
146. doWork();
147. }
148. catch (InterruptedException e) {
149. e.printStackTrace();
150. }
151. }
152.
153. /**
154. * 子线程写入固定值,写入成功则递减计数器www.2cto.com
155. *
156. * @throws InterruptedException
157. */
158. private void doWork() throws InterruptedException {
159. while (writer.isWorking()) {
160. boolean isWrited = writer.writeToOutput(num);
161. if (isWrited) {
162. end.countDown();
163. Thread.sleep(50); // 调整线程竞争,使得每个线程获取outList锁的几率均衡
164. }
165. }
166. }
167. }
168.
169. private class MockOutput {
170.
171. /** 用于终端显示的记录 */
172. private final StringBuilder stringBuilder;
173.
174. /** 需要写入的文本输出 */
175. private final PrintWriter printWriter;
176.
177. /** 文件名 */
178. private final String name;
179.
180. /** 最后一次写入的值 */