Java多线程实现同步——wait()和notify()实现

要求:子线程循环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();
			}
		}
	}
}

代码未经过测试,热心的朋友可以给我留言,支出修改的地方。

转载于:https://my.oschina.net/gaohongtian/blog/494845

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值