文档章节

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

文森特梵高
 文森特梵高
发布于 2015/08/20 00:57
字数 704
阅读 521
收藏 14

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

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

© 著作权归作者所有

共有 人打赏支持
上一篇: 常见算法的记录
下一篇: Java异常体系
文森特梵高
粉丝 2
博文 28
码字总数 15386
作品 0
广州
程序员
私信 提问
Java学习笔记--线程和多线程线程池(简单理解)

线程: 单核的cpu在一个时间片中只能执行一个应用程序 各个程序其实在做cpu的资源真多战而已 cpu做了快速的切换动作 疑问 :线程负责了代码 的执行,我们之前没有学过线程,为什么代码可以执...

codingcoge
05/02
0
0
Java多线程学习(四)等待/通知(wait/notify)机制

系列文章传送门: Java多线程学习(一)Java多线程入门 Java多线程学习(二)synchronized关键字(1) java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Ja...

一只蜗牛呀
04/16
0
0
JAVA多线程和并发基础面试问答

多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一。在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题。(校对注:...

LCZ777
2014/05/26
0
0
java基础thread——java5之后的多线程(浅尝辄止)

承上启下 虽然我们可以理解同步代码块和同步方法的锁对象问题,但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象L...

潇潇漓燃
06/03
0
0
安卓中高级开发工程师面试之——面试永远逃不掉的Java线程面试题

不管你是Java工程师还是安卓开发工程师,只要你是计算机开发工程师,你一定在面试中遇到过有关线程的问题。Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎。大...

小饼干的梦
10/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

《稻盛和夫经营学》读后感心得体会3180字范文

《稻盛和夫经营学》读后感心得体会3180字范文: 一代日本经营之圣稻盛和夫凭借刻苦勤奋的精神以及深植于佛教的商业道德准则,成为了“佛系”企业家的代表人物。在《稻盛和夫经营学》“领导人...

原创小博客
44分钟前
1
0
java框架学习日志-5(常见的依赖注入)

依赖注入(dependency injection) 之前提到控制反转(Inversion of Control)也叫依赖注入,它们其实是一个东西,只是看的角度不同,这章详细说一下依赖注入。 依赖——指bean对象创建依赖于...

白话
今天
2
0
红外接收器驱动开发

背景:使用系统的红外遥控软件没有反应,然后以为自己接线错误,反复测试,结果烧坏了一个红外接收器,信号主板没有问题。所以自己开发了一个红外接收器的python驱动。接线参见https://my.os...

mbzhong
今天
2
0
ActiveMQ消息传送机制以及ACK机制详解

AcitveMQ是作为一种消息存储和分发组件,涉及到client与broker端数据交互的方方面面,它不仅要担保消息的存储安全性,还要提供额外的手段来确保消息的分发是可靠的。 一. ActiveMQ消息传送机...

watermelon11
今天
2
0
HashTable和Vector为什么逐渐被废弃

HashTable,不允许键值为null,还一个就是put方法使用sychronized方法进行线程同步,单线程无需同步,多线程可用concurren包的类型。 如编程思想里面说的作为工具类,封闭性做的不好没有一个...

noob_chr
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部