文档章节

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

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

行业解决方案、产品招募中!想赚钱就来传!>>>

要求:子线程循环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
广州
程序员
私信 提问
加载中
请先登录后再评论。
Netty那点事(三)Channel与Pipeline

Channel是理解和使用Netty的核心。Channel的涉及内容较多,这里我使用由浅入深的介绍方法。在这篇文章中,我们主要介绍Channel部分中Pipeline实现机制。为了避免枯燥,借用一下《盗梦空间》的...

黄亿华
2013/11/24
2W
22
访问安全控制解决方案

本文是《轻量级 Java Web 框架架构设计》的系列博文。 今天想和大家简单的分享一下,在 Smart 中是如何做到访问安全控制的。也就是说,当没有登录或 Session 过期时所做的操作,会自动退回到...

黄勇
2013/11/03
3.4K
6
用vertx实现高吞吐量的站点计数器

工具:vertx,redis,mongodb,log4j 源代码地址:https://github.com/jianglibo/visitrank 先看架构图: 如果你不熟悉vertx,请先google一下。我这里将vertx当作一个容器,上面所有的圆圈要...

jianglibo
2014/04/03
3.9K
3
SQLServer实现split分割字符串到列

网上已有人实现sqlserver的split函数可将字符串分割成行,但是我们习惯了split返回数组或者列表,因此这里对其做一些改动,最终实现也许不尽如意,但是也能解决一些问题。 先贴上某大牛写的s...

cwalet
2014/05/21
9.6K
0
Swift百万线程攻破单例(Singleton)模式

一、不安全的单例实现 在上一篇文章我们给出了单例的设计模式,直接给出了线程安全的实现方法。单例的实现有多种方法,如下面: class SwiftSingleton { } 这段代码的实现,在shared中进行条...

一叶博客
2014/06/20
3.3K
16

没有更多内容

加载失败,请刷新页面

加载更多

鼠年吉祥,新年快乐

今天是大年初一,很高兴在过去一年中有您的陪伴,希望大家在新的一年中平安健康,一切顺利,加油。 邓飞 202001250539 于后园爷爷家 本文分享自微信公众号 - 育种数据分析之放飞自我(R-bre...

育种数据分析之放飞自
01/25
0
0
不烧脑、不耗时、全免费,带你0基础学Python

文末有福利 Python是人工智能的未来。 最近,电气和电子工程师协会( IEEE)发布了顶级编程语言交互排行榜:Python高居首位。 而且随着大数据和人工智能的发展,Python受到了越来越多程序员的...

kunjian
今天
11
0
R语言入门系列之一

写在前面 计算机语言的学习并不困难,关键是一定要由浅入深的实际操作练习。也许最开始的比较简单,学习者一带而过没有实际操作,之后的进一步学习很可能会陷入不知所云的困境,实际操作所带...

SYSU星空
2019/02/17
0
0
Istio-本地运行

概述 基于上一篇 Istio1.6-二进制编译和本地运行 但集中在 pilot-discovery 和 envoy(pilot-agent 大部分功能仅作为 envoy 的 watchdog,略过) NOTE: 以下的描述,相对路径都基于目录 /g...

深蓝苹果
47分钟前
9
0
基于Linux、C、JSON、Socket的编程实例(附代码)

点击上方「嵌入式大杂烩」,选择「置顶公众号」第一时间阅读编程笔记! 一、前言 之前在学习socket编程的时候有分享一个基于控制台的简易天气客户端的实现,当时提供的是window下的代码,最近...

学以解忧
2019/10/29
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部