Java多線程實現同步——wait()和notify()實現

要求:子線程循環5次,接着主線程循環10次,接着又回到子線程。如此循環50次。
java

實現以上要求的時候,除了直白的面向過程的實現,能夠考慮面向對象的寫法。多線程

根據高內聚的原裝,將子線程和主線程的操做都封裝一塊兒。dom

經過wait()和notify()進行同步。ide

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」.this

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();
			}
		}
	}
}

代碼未通過測試,熱心的朋友能夠給我留言,支出修改的地方。spa

相關文章
相關標籤/搜索