要求:子线程循环5次,接着主线程循环10次,接着又回到子线程。如此循环50次。
实现以上要求的时候,除了直白的面向过程的实现,可以考虑面向对象的写法。
根据高内聚的原装,将子线程和主线程的操作都封装一起。
通过wait()和notify()进行同步。
class Business {
private boolean shouldSub = true;
public synchronized void sub(int k) {
if (shouldSub) {
for (int i=0 ; i<5 ; i++) {
System.out.println("sub thread inner of " + i + " ,outer " + k);
}
shouldSub = false;
this.notifyAll();
} else {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void main(int k) {
if (!shouldSub) {
for (int i=0 ; i<10 ; i++) {
System.out.println("main thread inner of " + i + " ,outer " + k);
}
shouldSub = true;
this.notifyAll();
} else {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class TraditionalThreadCommucation {
public static void main(String[] args) {
final Business business = new Business();
new Thread(new Runnable() {
@Override
public void run() {
for (int k=0; k<50 ;k++){
business.sub(k);
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
for (int k=0; k<50 ;k++){
business.main(k);
}
}
}).start();
}
}
根据以上的设计思路,我们来解另一道题:
一个文件中有10000个数,用Java实现一个多线程程序将这个10000个数输出到5个不用文件中(不要求输出到每个文件中的数量相同)。要求启动10个线程,两两一组,分为5组。每组两个线程分别将文件中的奇数和偶数输出到该组对应的一个文件中,需要偶数线程每打印10个偶数以后,就将奇数线程打印10个奇数,如此交替进行。同时需要记录输出进度,每完成1000个数就在控制台中打印当前完成数量,并在所有线程结束后,在控制台打印”Done”.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.Random;
public class MyPrintByThread {
public static void main(String[] args) {
try {
PrintWriter pw = new PrintWriter(new FileWriter(new File("input.txt")),true);
Random random = new Random();
for (int i=0 ; i<10000 ; i++) {
pw.print(Math.abs(random.nextInt()%100) + " ");
}
pw.flush();
pw.close();
BufferedReader reader = new BufferedReader(new FileReader("input.txt"));
String str = reader.readLine();
reader.close();
String[] strs = str.split(" ");
int j=0;
for (int i=0 ; i<5 ;i++) {
int records[] = new int[2000];
for (int k=0 ; k<2000 ; k++) {
records[k] = Integer.parseInt(strs[j]);
j++;
}
PrintWriter writer = new PrintWriter(new FileWriter(new File("output"+i+".txt")),true);
final Business business = new Business(writer, records);
new Thread(new Runnable() {
@Override
public void run() {
business.printEven();
}
});
new Thread(new Runnable() {
@Override
public void run() {
business.printOdd();
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Business {
private boolean shouldEven = true;
private int[] subRecords;
private PrintWriter pw;
private int evenPointer = 0;
private int oddPointer = 0;
public Business(PrintWriter pw,int[] subRecords) {
this.pw = pw;
this.subRecords = subRecords;
}
public synchronized void printEven() {
if (shouldEven) {
if (evenPointer <= subRecords.length) {
for (int i=0 ; i<10 ;) {
if (subRecords[evenPointer] % 2 == 0) {
pw.print(subRecords[evenPointer] + " ");
if (evenPointer % 1000 == 0)
System.out.println("已经打印:" + evenPointer);
i++;
}
evenPointer++;
}
}
shouldEven = false;
this.notify();
} else {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void printOdd() {
if (!shouldEven) {
if (oddPointer <= subRecords.length) {
for (int i=0 ; i<10 ;) {
if (subRecords[oddPointer] % 2 != 0) {
pw.print(subRecords[oddPointer] + " ");
if (evenPointer % 1000 == 0)
System.out.println("已经打印:" + oddPointer);
i++;
}
oddPointer++;
}
}
shouldEven = true;
this.notify();
} else {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
代码未经过测试,热心的朋友可以给我留言,支出修改的地方。