`
xmong
  • 浏览: 259127 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

java多线程设计模式之读写文件模式

阅读更多

Java实现多线程读写数据

实现需求如下:
当数据没有写线程修改数据时,可以多个读线程读取数据。
当数据有写线程修改数据时,读线程等待,其他写线程也等待,只能有一个写线程修改数据。
当数据没有读线程读数据时,可以有一个写线程修改数据。
当数据有读线程读数据时,写线程不能修改数据。

设计如下:

Data:数据类,用于读写数据的类
ReadWriteLock:读写锁类,实现读写锁控制
ReaderThread:读线程,负责读取数据
WriterThread:写线程,负责写数据
Main:main类

实现如下:

Data:数据类
package com.thread.readwriter;

/**
 * 数据类
 * @author Administrator
 *
 */
public class Data {

	//写入数据缓存区
	private char[] buffer = new char[10]; 
	//数据的读写锁
	private final ReadWriteLock lock = new ReadWriteLock();
	
	/**
	 * 读取数据
	 * @return
	 * @throws InterruptedException
	 */
	public char[] read() throws InterruptedException{
		lock.readLock();
		try {
			char[] buffer = doRead();
			System.out.println(Thread.currentThread().getName()+" read "+String.valueOf(buffer));
			return buffer;
		} finally {
			lock.readUnlock();
		}
	}
	
	/**
	 * 以字符为单位一次一次的读取缓冲区的数据
	 * @return
	 */
	public char[] doRead(){
		char[] newbuffer = new char[buffer.length];
		for (int i = 0; i < buffer.length; i++) {
			newbuffer[i] = buffer[i];
		}
		return buffer;
	}
	
	/**
	 * 写入缓冲区数据
	 * @param c
	 * @throws InterruptedException
	 */
	public void write(char c) throws InterruptedException{
		lock.writeLock();
		try {
			System.out.println(Thread.currentThread().getName()+" write "+c);
			doWrite(c);
		} finally {
			lock.writeUnlock();
		}
	}
	
	/**
	 * 以字符为单位一次一次地写入缓冲区
	 * @param c
	 */
	public void doWrite(char c){
		for (int i = 0; i < buffer.length; i++) {
			buffer[i] = c;
		}
	}
	
}


ReadWriteLock:读写锁类
package com.thread.readwriter;

/**
 * 读写锁类
 * @author Administrator
 *
 */
public class ReadWriteLock {

	
	private int readingNum = 0; //正在读数据的线程数
	private int writingNum = 0; //正在写数据的线程数
	
	private int waitingNum = 0; //正在等待写数据的线程数
	private boolean writerPriority = true; //写数据优先
	
	/**
	 * 读数据上锁
	 * @throws InterruptedException
	 */
	public synchronized void readLock() throws InterruptedException{
		while(writingNum > 0 || (waitingNum > 0 && writerPriority)){
			wait();
		}
		readingNum++;
	}
	
	/**
	 * 读数据解锁
	 */
	public synchronized void readUnlock(){
		readingNum--;
		writerPriority = true;
		notifyAll();
	}
	
	/**
	 * 写数据上锁
	 * @throws InterruptedException
	 */
	public synchronized void writeLock() throws InterruptedException{
		waitingNum++;
		while(readingNum > 0 || writingNum >0 ){
			try {
				wait();
			} finally {
				waitingNum--;
			}
		}
		writingNum++;
	}
	
	/**
	 * 写数据解锁 
	 */
	public synchronized void writeUnlock(){
		writingNum--;
		writerPriority = false;
		notifyAll();
	}
	
}


ReaderThread:读线程类
package com.thread.readwriter;

import java.util.Random;

public class ReaderThread extends Thread{
	
	//数据
	private final Data data;
	//随机数
	private final Random random = new Random();
	
	/**
	 * 读线程构造方法
	 * @param name 线程名称
	 * @param data 注入需要读的数据
	 */
	public ReaderThread(String name, Data data){
		super(name);
		this.data = data;
	}
	
	/**
	 * 读取数据
	 */
	public void run(){
		while(true){
			try {
				data.read();
				Thread.sleep(random.nextInt(500));//随机休息
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
}

WriterThread:写线程类
package com.thread.readwriter;

/**
 * 写入线程类
 * @author Administrator
 *
 */
public class WriterThread extends Thread{

	//数据
	private final Data data;
	//写入字符串
	private final String str;
	//写字符串下标
	private int index = 0;
	
	/**
	 * 写入线程构造方法
	 * @param name 线程名称
	 * @param data 数据存储区
	 * @param str 写入字符串
	 */
	public WriterThread(String name, Data data, String str){
		super(name);
		this.data = data;
		this.str = str;
	}
	
	/**
	 * 写入字符串
	 */
	public void run(){
		while(true){
			try {
				char c = nextChar();
				data.write(c);
				Thread.sleep(3000); //随机休息
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 循环从字符串中获取字符
	 * @return
	 */
	private char nextChar(){
		char c = str.charAt(index);
		index++;
		if(index >= str.length()){
			index = 0;
		}
		return c;
	}
}

Main:main类

package com.thread.readwriter;

/**
 * main类
 * @author Administrator
 *
 */
public class Main {

	
	public static void main(String[] args) {
		//数据区
		Data data = new Data();
		//启动写线程
		new WriterThread("WriterThread.1", data, "abcdefghijklmnopkrstuvwxyz").start();
		new WriterThread("WriterThread.2", data, "ABCDEFGHIJKLMNOPQRSTUVWXYZ").start();
		//启动读线程
		new ReaderThread("ReaderThread.1", data).start();
		new ReaderThread("ReaderThread.2",data).start();
		new ReaderThread("ReaderThread.3",data).start();
		new ReaderThread("ReaderThread.4",data).start();
	}
}

执行结果:

WriterThread.1 write a
WriterThread.2 write A
ReaderThread.2 read AAAAAAAAAA
WriterThread.2 write B
ReaderThread.2 read BBBBBBBBBB
WriterThread.1 write b
ReaderThread.4 read bbbbbbbbbb
WriterThread.2 write C
ReaderThread.4 read CCCCCCCCCC
ReaderThread.2 read CCCCCCCCCC
WriterThread.1 write c
ReaderThread.3 read cccccccccc
WriterThread.2 write D
ReaderThread.2 read DDDDDDDDDD
WriterThread.1 write d
ReaderThread.1 read dddddddddd
WriterThread.2 write E
ReaderThread.1 read EEEEEEEEEE
WriterThread.1 write e
ReaderThread.4 read eeeeeeeeee
WriterThread.1 write f
WriterThread.2 write F
ReaderThread.1 read FFFFFFFFFF
ReaderThread.4 read FFFFFFFFFF
。。




分享到:
评论

相关推荐

    java源码包---java 源码 大量 实例

    Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密  Java非对称加密源程序代码实例,本例中使用RSA加密技术,...

    JAVA上百实例源码以及开源项目

    Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密  Java非对称加密源程序代码实例,本例中使用RSA加密技术,...

    2023Java高频面试题

    Java面试题主要涉及Java语言本身、常用的Java框架和技术、面向对象编程、多线程编程、算法和数据结构等方面。通常包括以下主要内容: Java基础知识:Java的基本数据类型、变量、运算符、控制语句等基础概念。 面向...

    华为内部java考题

    (2)多线程同步机制; (3)文件读写; (4)XML解析、基本的正则表达式; (5)类的加载和反射机制 (6)软件的需求分析以及逻辑思维能力; (7)软件设计(设计模式、类图)、编辑、编译、调测能力。

    JAVA上百实例源码以及开源项目源代码

    Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密  Java非对称加密源程序代码实例,本例中使用RSA加密技术,...

    java源码包4

    Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密  Java非对称加密源程序代码实例,本例中使用RSA加密技术...

    java源码包3

    Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密  Java非对称加密源程序代码实例,本例中使用RSA加密技术...

    java源码包2

    Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密  Java非对称加密源程序代码实例,本例中使用RSA加密技术...

    JAVA_API1.6文档(中文)

    java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...

    北京百度java面试题大全

    多线程编程:涉及线程的创建、同步与互斥、线程池、线程间通信等多线程编程的知识。 IO操作:包括文件读写、字符流和字节流、序列化与反序列化等IO操作的相关知识。 JDBC和数据库:涉及JDBC的使用、连接数据库、...

    Java基础语法面试题.docx

    Java基础语法面试题资源通常是指帮助准备...设计模式:介绍常见的设计模式,如单例模式、工厂模式、观察者模式等。 常见算法和数据结构:可能包含一些常见的算法问题,如查找、排序、递归等,以及与之相关的数据结构。

    最新Java面试题视频网盘,Java面试题84集、java面试专属及面试必问课程

    │ │ 9.JAVA并发编程之多线程并发同步业务场景与解决方案.wmv │ │ │ ├─10.微服务架构之Spring Cloud Eureka 场景分析与实战 │ │ 10.微服务架构之Spring Cloud Eureka 场景分析与实战.wmv │ │ │ ├─11....

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密 Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义...

    【白雪红叶】JAVA学习技术栈梳理思维导图.xmind

    多线程与并发 GC机制 GC收集器类型 串行 CMS 并行 G1 算法 复制 标记清理 标记整理 分区 新生代 eden survivor 老年代(old区) 永久代(perm区) 版本变化 1.5 1.6 1.7 1.8 1.9 IO/NIO IO...

    Java 1.6 API 中文 New

    java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...

    JAVA 范例大全 光盘 资源

    实例70 读写Properties文件 170 实例71 配置Properties带附件发送邮件 175 实例72 资源国际化(Properties) 179 常见问题 读取Properties文件出现中文乱码 182 第9章 Java异常处理与反射机制 183 实例73 运用...

    Java JDK实例宝典

    7 一个支持多线程的服务器框架 13. 8 代理服务器 13. 9 Telnet客户端 13. 10 UDP编程 13. 11 聊天室服务器端 13. 12 聊天室客户端 13. 13 FTP客户端 第14章 数据库 14. 1 连接各种...

    java api最新7.0

    java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...

    成百上千个Java 源码DEMO 3(1-4是独立压缩包)

    Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密 Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义...

Global site tag (gtag.js) - Google Analytics