Java多线程之~~~ReadWriteLock 读写分离的多线程实现

在多线程开发中,经常会出现一种情况,我们希望读写分离。就是对于读取这个动作来说,可以同时有多个线程同

时去读取这个资源,但是对于写这个动作来说,只能同时有一个线程来操作,而且同时,当有一个写线程在操作这个资

源的时候,其他的读线程是不能来操作这个资源的,这样就极大的发挥了多线程的特点,能很好的将多线程的能力发挥

出来。

在Java中,ReadWriteLock这个接口就为我们实现了这个需求,通过他的实现类ReentrantReadWriteLock我们可

以很简单的来实现刚才的效果,下面我们使用一个例子来说明这个类的用法。

package com.bird.concursey.charpet3;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class PricesInfo {

	private double price1;

	private double price2;

	private ReadWriteLock lock;

	public PricesInfo() {
		price1 = 1.0;
		price2 = 2.0;
		lock = new ReentrantReadWriteLock();
	}

	public double getPrice1() {
		//读取资源锁定
		lock.readLock().lock();
		double value = price1;
		lock.readLock().unlock();
		return value;
	}

	public double getPrice2() {
		lock.readLock().lock();
		double value = price2;
		lock.readLock().unlock();
		return value;
	}

	public void setPrices(double price1, double price2) {
		lock.writeLock().lock();
		this.price1 = price1;
		this.price2 = price2;
		lock.writeLock().unlock();
	}

}

下面是读和写两个不同的类

package com.bird.concursey.charpet3;

public class Reader implements Runnable {

	private PricesInfo pricesInfo;

	public Reader(PricesInfo pricesInfo) {
		this.pricesInfo = pricesInfo;
	}

	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			System.out.printf("%s: Price 1: %f\n", Thread.currentThread()
					.getName(), pricesInfo.getPrice1());
			System.out.printf("%s: Price 2: %f\n", Thread.currentThread()
					.getName(), pricesInfo.getPrice2());
		}
	}

}
package com.bird.concursey.charpet3;

public class Writer implements Runnable {

	private PricesInfo pricesInfo;

	public Writer(PricesInfo pricesInfo) {
		this.pricesInfo = pricesInfo;
	}

	@Override
	public void run() {
		for (int i = 0; i < 3; i++) {
			System.out.printf("Writer: Attempt to modify the prices.\n");
			pricesInfo.setPrices(Math.random() * 10, Math.random( ) * 8);
			System.out.printf("Writer: Prices have been modified.\n");
			try {
				Thread.sleep(2);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		PricesInfo pricesInfo = new PricesInfo();
		Reader readers[] = new Reader[5];
		Thread threadsReader[] = new Thread[5];
		for (int i = 0; i < 5; i++){
			readers[i] = new Reader(pricesInfo);
			threadsReader[i] = new Thread(readers[i]);
		}
		Writer writer = new Writer(pricesInfo);
		Thread threadWriter = new Thread(writer);
		for (int i = 0; i < 5; i++){
			threadsReader[i].start();
		}
		threadWriter.start();
	}
}
时间: 2024-12-29 13:21:02

Java多线程之~~~ReadWriteLock 读写分离的多线程实现的相关文章

java实现mysql数据库读写分离之定义多数据源方式

该示例是基于spring提供的AbstractRoutingDataSource,实现了一个动态数据源的功能,在spring配置中定义多个数据库分为主.从数据库,实现效果为当进行保存和修改记录时则对主表操作,查询则对从表进行操作,从而实现对数据库表的读写分离.这样做有利于提高网站的性能,特别是在数据库这一层.因为在实际的应用中,数据库都是读多写少(读取数据的频率高,更新数据的频率相对较少),而读取数据通常耗时比较长,占用数据库服务器的CPU较多,从而影响用户体验.我们通常的做法就是把查询从主库中

java 使用spring实现读写分离

最近上线的项目中数据库数据已经临近饱和,最大的一张表数据已经接近3000W,百万数据的表也有几张,项目要求读数据(select)时间不能超过0.05秒,但实际情况已经不符合要求,explain建立索引,使用redis,ehcache缓存技术也已经满足不了要求,所以开始使用读写分离技术,可能以后数据量上亿或者更多的时候,需要再去考虑分布式数据库的部署,但目前来看,读写分离+缓存+索引+表分区+sql优化+负载均衡是可以满足亿级数据量的查询工作的,现在就一起来看一下亲测可用的使用spring实现读写

Java实现数据库的读写分离

引言 1.读写分离:可以通过Spring提供的AbstractRoutingDataSource类,重写determineCurrentLookupKey方法,实现动态切换数据源的功能:读写分离可以有效减轻写库的压力,又可以把查询数据的请求分发到不同读库: 2.写数据库:当调用insert.update.delete及一些实时数据用到的库: 3.读数据库:当调用select查询数据用到的库: 4.JaveWeb工程通过AbstractRoutingDataSource类实现读写分离: 一.jdb

MySQL 主从复制与读写分离

Mysql主从复制作用原理 1.在业务复杂的系统中,有这么一个情景,有一句sql语句需要锁表,导致暂时不能使用读的服务,那么就很影响运行中的业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运作.2.做数据的热备3.架构的扩展.业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能.mysql主从复制是一个异步的复制过程,主库发送更新事件到从库,从库读取更新记录,并执行更新记

mysql-配置主从数据库,实现读写分离

主从分离的原则:所有的写操作在主数据库中进行,因为主从分离的原理是涉及到同步数据,那就可能会出现延迟或者其他问题,就可能会出现脏数据. 所以,在从库中进行的读操作也必须是有一定容忍性的数据,例如日志等. 例如需要注意,如果一个业务中有读和写的操作. 那么这个操作的库必须是主库,因为这个涉及到事务,需要非常小心. 主从同步的原理: 从数据库后台线程请求主数据库的更新数据,主数据库后台线程接收到请求后会读取bin-log文件内容,然后放到从库的请求响应中. 从库接收到响应后,会将接收到的内容放到re

MySQL主从复制与读写分离(实践篇)

MySQL主从复制的类型 基于语句的复制(默认) 在主服务器上执行的语句,从服务器执行同样的语句 基于行的复制 把改变的内容复制到从服务器 混合类型的复制 一旦发现基于语句无法精确复制时,就会采用基于行的复制 主从复制的过 MySQL读写分离原理 读写分离就是只在主服务器上写,只在从服务器上读 主数据库处理事务性查询,而从数据库处理select查询 数据库复制被用来把事务性查询导致的变更同步到集群中的从数据库 读写分离的过程 实践操作 实验环境 amoeba服务器IP地址:192.168.144

JAVA多线程 &amp; 同步关键词synchronized &amp; ReadWriteLock读写文件

在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了,但是一个类只能继承一个父类,这是此方法的局限. 1 public class Actor extends Thread { 2 public void run(){ 3 //线程执行的操作 4 } 5 } 在实际开发中一个多线程的操作很少使用Thread类,而是通过Run

多线程.NET条码读写控件自动检测条码的方位条形码控件VintaSoftBarcode

VintaSoftBarcode.NET Library 条形码控件是一个完美的条码读写.NET 库,支持从数码图片读取条码或者生成数码图片条码. 具体功能: 支持多线程 支持创建条码图片 支持为生成的条码指定大小和分辨率 拥有许多选项控制条码创建 支持从图片对象.图片文件.和PDF文档读取条码 编程环境:.NET 框架. 这是一个可完全操纵的.NET 库,保证在.NET 框架中实现快速工作. 能够识别图片中的所有条码. 确认已识别的条码类型. 返回条码的字符串值. 自动检测条码的方位. 返回条

java网络编程学习之——构建基于多线程的网络通信模型1

该例展示了多用户/服务器通信模型,包含三个文件:Server.java   ServerThread.java 和Client.java类.其中ServerThread类支持多线程,为客户提供的所有操作都封装到该类中,该类的构造方法ServerThread(Socket socket)接收一个套接字对象,用来与客户进行数据通信.Server类是一个应用程序,其main方法中通过一个无限的whlie循环,等待并监听多个用户连接请求(本例中只演示了一个客户请求),每个客户的连接都由服务器端的一个单独