一个文件中有10000个数,用Java实现一个多线程程序将这个10000个数输出到5个不用文件中(不要求输出到每个文件中的数量相同)。要求启动10个线程,两两一组,分为5组。每组两个线程分别将文件中的奇数和偶数输出到该组对应的一个文件中,需要偶数线程每打印10个偶数以后,就将奇数线程打印10个奇数,如此交替进行。同时需要记录输出进度,每完成1000个数就在控制台中打印当前完成数量,并在所有线程结束后,在控制台打印”Done”.
试着写了一下,可以运行。代码如下:
package com.cn.edu.tju.thead;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
public class TestFile {
static int count = 0;// 记录线程读取的总数
static Object object = new Object();// 修改10个线程中count值时的锁
public static void main(String[] args) throws IOException {
String file = "input.txt";
inputFile(file);// 随机生成10000个数
BufferedReader br = new BufferedReader(new FileReader(new File(file)));
String s = br.readLine();
br.close();
String[] stringArray = s.split(" ");
int index = 0;
for (int i = 0; i < 5; i++) {
int[] readArray = new int[2000];
for (int j = 0; j < 2000; j++) {
readArray[j] = Integer.parseInt(stringArray[index++]);
}
// 输出文件
PrintWriter printWriter = new PrintWriter(new File("input"
+ (i + 1) + ".txt"));
Object objectPre = new Object();// 每组线程中的锁
Even even = new Even();// 等待通知机制的条件
Point point = new Point();// 记录当前偶数 奇数的位置
PrintEvenFile printEvenFile = new PrintEvenFile(printWriter,
readArray, objectPre, even, point);// 处理偶数
PrintOddFile printOddFile = new PrintOddFile(printWriter,
readArray, objectPre, even, point);// 处理奇数
new Thread(printEvenFile).start();
new Thread(printOddFile).start();
}
}
// 随机生成10000个数
static void inputFile(String name) {
PrintWriter pw = null;
try {
pw = new PrintWriter(new File(name));
Random random = new Random();
for (int i = 0; i < 10000; i++) {
int randomValue = random.nextInt(100);
pw.append(randomValue + " ");
}
pw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
// 等待通知机制的条件
static class Even {
boolean isEven = true;
}
// 记录当前偶数 奇数的位置
static class Point {
int evenPoint = 0;// 每组线程中偶数线程读取到的位置
int oddPoint = 0;// //每组线程中奇数线程读取到的位置
}
// 处理偶数
static class PrintEvenFile implements Runnable {
PrintWriter printWriter = null;
int[] readArray = null;
Object lock = null;
Even even = null;
Point point = null;
public PrintEvenFile(PrintWriter printWriter, int[] readArray,
Object lock, Even even, Point point) {
this.printWriter = printWriter;
this.readArray = readArray;
this.point = point;
this.lock = lock;
this.even = even;
}
@Override
public void run() {
while (readEvenFile()) {
}
}
boolean readEvenFile() {
synchronized (lock) {
try {
while (!even.isEven)
lock.wait();
for (int i = 0; i < 10;) {
if (point.evenPoint >= 2000) {
break;
}
if (readArray[point.evenPoint] % 2 == 0) {
printWriter
.append(readArray[point.evenPoint] + " ");
printWriter.flush();
i++;
synchronized (object) {
count++;
if (count % 1000 == 0) {
System.out.println("当前完成数量:" + count);
if (count == 10000) {
System.out.println("Done!");
}
}
}
}
point.evenPoint = point.evenPoint + 1;
}
even.isEven = false;
lock.notify();
if (point.evenPoint >= 2000 && point.oddPoint >= 2000) {
printWriter.close();
return false;
}
return true;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return true;
}
}
// 处理奇数
static class PrintOddFile implements Runnable {
PrintWriter printWriter = null;
int[] readArray = null;
Object lock = null;
Even even = null;
Point point = null;
public PrintOddFile(PrintWriter printWriter, int[] readArray,
Object lock, Even even, Point point) {
this.printWriter = printWriter;
this.readArray = readArray;
this.point = point;
this.lock = lock;
this.even = even;
}
@Override
public void run() {
while (readEvenFile()) {
}
}
boolean readEvenFile() {
synchronized (lock) {
try {
while (even.isEven)
lock.wait();
for (int i = 0; i < 10;) {
if (point.oddPoint >= 2000) {
break;
}
if (readArray[point.oddPoint] % 2 == 1) {
printWriter.append(readArray[point.oddPoint] + " ");
printWriter.flush();
i++;
synchronized (object) {
count++;
if (count % 1000 == 0) {
System.out.println("当前完成数量:" + count);
if (count == 10000) {
System.out.println("Done!");
}
}
}
}
point.oddPoint = point.oddPoint + 1;
}
even.isEven = true;
lock.notify();
if (point.evenPoint >= 2000 && point.oddPoint >= 2000) {
printWriter.close();
return false;
}
return true;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return true;
}
}
}