文档章节

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

文森特梵高
 文森特梵高
发布于 2015/08/20 00:57
字数 704
阅读 507
收藏 14
点赞 0
评论 0

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

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

© 著作权归作者所有

共有 人打赏支持
文森特梵高
粉丝 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多线程和并发基础面试问答

原文链接 译文连接 作者:Pankaj 译者:郑旭东 校对:方腾飞 多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一。在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢...

雷神雨石
2014/07/19
0
2
JAVA多线程和并发基础面试问答

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

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

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

潇潇漓燃
06/03
0
0
JAVA多线程和并发基础面试问答

Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一...

清风傲剑
2014/12/06
0
0
JAVA多线程和并发基础面试问答

Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一...

hanzhankang
2014/01/20
0
0
java并发编程(2)——wait和notify解析

JAVA的进程同步是通过synchronized()来实现的,需要说明的是,JAVA的synchronized()方法类似于操作系统概念中的互斥内存块,在JAVA中的Object类型中,都是带有一个内存锁的,在有线程获取该内...

十二缸帕萨特
2014/04/12
0
0
【转】15个顶级Java多线程面试题及回答

Java 线程面试问题   在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分。如果你想获得任何股票投资银行的前台资讯职位,那么你应该准备很多关于多线程的问题。在投资银行业务...

一只死笨死笨的猪
2014/09/30
0
0
15个顶级Java多线程面试题及回答

Java 线程面试问题 在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分。如果你想获得任何股票投资银行的前台资讯职位,那么你应该准备很多关于多线程的问题。在投资银行业务中多...

LCZ777
2014/05/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

打印斐波那契数

package com.jerry.ch04;public class PrintFibonacci {public static void main(String[] args) {for (int i=0; i<10; i++) {System.out.print(fib(i) + " ");}......

JerryNing
11分钟前
0
0
shell编程

一、shell脚本介绍

人在艹木中
12分钟前
0
0
istio 0.8 遥测 案例

==============遥测===================================== 演示如何从网格中收集遥测信息。 分布式跟踪。如何配置代理以向Zipkin或Jaeger发送跟踪请求 收集度量标准和日志。此任务说明如何配...

xiaomin0322
14分钟前
0
0
ND4J求多元线性回归以及GPU和CPU计算性能对比

上一篇博客《梯度下降法求多元线性回归及Java实现》简单了介绍了梯度下降法,并用Java实现了一个梯度下降法求回归的例子。本篇博客,尝试用dl4j的张量运算库nd4j来实现梯度下降法求多元线性回...

冷血狂魔
15分钟前
0
0
springboot常用注解

@SpringBootApplication: 包含@Configuration、@EnableAutoConfiguration、@ComponentScan 通常用在主类上。 @Service: 用于标注业务层组件。 @RestController: 用于标注控制层组件(如strut...

GoldenVein
21分钟前
1
0
如何进行大数据的入门级学习?

不知道你是计算机专业应届生还是已经从业者。总之,有java基础的学生学习大数据会轻松很多,零基础的小白都需要从java和linux学起。 如果你是一个学习能力特别强,而且自律性也很强的人的话可...

董黎明
35分钟前
0
0
使用Parcelable传递复杂参数

最近做AIDL传递对象,对象必须实现Parcelable的方法才可以被传递。 @Override    public int describeContents() {//这个 默认返回0就行了。        return 0;    }    ...

火云
36分钟前
0
0
十大Intellij IDEA快捷键

Intellij IDEA中有很多快捷键让人爱不释手,stackoverflow上也有一些有趣的讨论。每个人都有自己的最爱,想排出个理想的榜单还真是困难。以前也整理过Intellij的快捷键,这次就按照我日常开发...

HJCui
46分钟前
0
0
word 使用mathtype 编写 数学公式

下载安装,这个链接命名。。。。 http://www.mathtype.cn/xiazai.html 安装之后会多出一个选项 使用内联方式插入图表 编写公式的界面 设置支持latex 语法 输入公式回车就可以看到结果...

阿豪boy
今天
0
0
Promise

定义 Promise是异步编程的一种解决方案,所谓Promise就是一个容器,里面保存着某个未来才会结束的事件(通常是一个一步操作)的结果。 特点: 2.1 对象的状态不受外界影响,三种状态pending...

litCabbage
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部