Java并发学习之十五——使用读写锁同步数据访问

本文是学习网络上的文章时的总结,感谢大家无私的分享。

读写锁重要的是写锁的使用,只用一个入口。

下面是读写锁使用的例子

package chapter2;

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

public class PricesInfo {
	private int price1;
	private int price2;
	private ReadWriteLock lock;
	public PricesInfo(){
		price1 = 1;
		price2 = 1;
		lock = new ReentrantReadWriteLock();

	}
	public int getPrice1() {
		lock.readLock().lock();
		int value = price1;
		lock.readLock().unlock();
		return value;
	}
	public void setPrice1(int price1) {
		this.price1 = price1;
	}
	public int getPrice2() {
		lock.readLock().lock();
		int value = price2;
		lock.readLock().unlock();
		return value;
	}
	public void setPrice2(int price2) {
		this.price2 = price2;
	}

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

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 2:%d\n", Thread.currentThread().getName(),pricesInfo.getPrice2());
			System.out.printf("%s:Price 1:%d\n", Thread.currentThread().getName(),pricesInfo.getPrice1());
		}

	}
}
package chapter2;

import java.util.Random;

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++){
			int p1 = new Random().nextInt(47);
			int p2 = new Random().nextInt(47)*10;

			System.out.println("Writer:Attempt to modify the prices."+p1+"    price2:"+p2);
			pricesInfo.setPrices(p1, p2);
			System.out.println("Writer:Prices have been modified."+p1+"    price2:"+p2);
			try {
				Thread.sleep(2);
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
	}
}
package chapter2;

public class Main6 {

	/**
	 * <p>
	 * </p>
	 * @author zhangjunshuai
	 * @date 2014-9-17 上午11:17:50
	 * @param args
	 */
	public static void main(String[] args) {

		PricesInfo pricesInfo = new PricesInfo();
		Reader reader[] = new Reader[5];
		Thread threadsReader[] = new Thread[5];
		for (int i = 0; i < threadsReader.length; i++) {
			reader[i] = new Reader(pricesInfo);
			threadsReader[i]=new Thread(reader[i]);
		}
		Writer writer = new Writer(pricesInfo);
		Thread threadWriter = new Thread(writer);
		for (int i = 0; i < threadsReader.length; i++) {
			threadsReader[i].start();
		}
		threadWriter.start();
	}

}
时间: 2024-09-29 21:19:50

Java并发学习之十五——使用读写锁同步数据访问的相关文章

【死磕Java并发】-----J.U.C之读写锁:ReentrantReadWriteLock

此篇博客所有源码均来自JDK 1.8 重入锁ReentrantLock是排他锁,排他锁在同一时刻仅有一个线程可以进行访问,但是在大多数场景下,大部分时间都是提供读服务,而写服务占有的时间较少.然而读服务不存在数据竞争问题,如果一个线程在读时禁止其他线程读势必会导致性能降低.所以就提供了读写锁. 读写锁维护着一对锁,一个读锁和一个写锁.通过分离读锁和写锁,使得并发性比一般的排他锁有了较大的提升:在同一时间可以允许多个读线程同时访问,但是在写线程访问时,所有读线程和写线程都会被阻塞. 读写锁的主要特

Java并发学习之十六——线程同步工具之信号量(Semaphores)

本文是学习网络上的文章时的总结,感谢大家无私的分享. 当一个线程想要访问某个共享资源,首先,它必须获得semaphore.如果semaphore的内部计数器的值大于0,那么semaphore减少计数器的值并允许访问共享的资源.计数器的值大于0表示,有可以自由使用的资源,所以线程可以访问并使用它们. package chapter3; import java.util.concurrent.Semaphore; public class PrintQueue2 { private final Se

十五、读写锁

一.简介 有时候我们对资源的修改操作非常地少,但是读取的频率却很高.如果采用一般的互斥锁,那么大量的读取操作也需要做等待.基于读写分离的思想,我们可以使用JDK的读写锁来处理这种情况. 1)读读不互斥: 2)读写互斥. 3)写写互斥 JDK文档地址:http://tool.oschina.net/uploads/apidocs/jdk-zh/java/util/concurrent/locks/ReentrantReadWriteLock.html 二.代码示例 import java.util

Java并发学习之十九——线程同步工具之Phaser

本文是学习网络上的文章时的总结.感谢大家无私的分享. JDK 1.7 加入了一个新的工具Phaser.Phaser的在功能上与CountDownLatch有部分重合. 以下使用Phaser类来同步3个并发任务. 这3个任务会在3个不同的目录和它们的子目录中搜索扩展名是.log的文件. 这个任务被分成3个步骤: 1. 在指定的目录和子目录中获得文件扩展名为.log的文件列表. 2. 在操控台打印结果. 在步骤1和步骤2的结尾我们要检查列表是否为空. 假设为空.那么线程直接结束执行并从phaser类

Java并发学习之十四——使用Lock同步代码块

本文是学习网络上的文章时的总结,感谢大家无私的分享. Java提供另外的机制用来同步代码块.它比synchronized关键字更加强大.灵活.Lock 接口比synchronized关键字提供更多额外的功能.在使用Lock时需要注意的是要释放Lock锁. package chapter2; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /* * 打印队列 */ pu

Java基础学习笔记十五 集合、迭代器、泛型

Collection 集合,集合是java中提供的一种容器,可以用来存储多个数据. 在前面的学习中,我们知道数据多了,可以使用数组存放或者使用ArrayList集合进行存放数据.那么,集合和数组既然都是容器,它们有啥区别呢? 数组的长度是固定的.集合的长度是可变的. 集合中存储的元素必须是引用类型数据 集合继承关系图 ArrayList的继承关系: 查看ArrayList类发现它继承了抽象类AbstractList同时实现接口List,而List接口又继承了Collection接口.Collec

Java并发学习之十八——线程同步工具之CyclicBarrier

本文是学习网络上的文章时的总结,感谢大家无私的分享. CyclicBarrier 类有一个整数初始值,此值表示将在同一点同步的线程数量.当其中一个线程到达确定点,它会调用await() 方法来等待其他线程.当线程调用这个方法,CyclicBarrier阻塞线程进入休眠直到其他线程到达.当最后一个线程调用CyclicBarrier 类的await() 方法,它唤醒所有等待的线程并继续执行它们的任务. 注意比较CountDownLatch和CyclicBarrier: 1.CountDownLatc

Java并发学习之十——用线程工厂创建线程

本文是学习网络上的文章时的总结,感谢大家无私的分享. 1.工厂模式是最有用的设计模式.它是一个创造模式,还有他的目的是创建一个 或者几个类对象的对象.有了这个工厂,我们有这些优势集中创建对象: 更简单的改变了类的对象创建或者说创建这些对象的方式: 更简单的为了限制的资源限制了对象的创建. 更简单的生成创建对象的统计数据. 2.Java提供一个接口,ThreadFactory接口实现一个线程对象工厂 package chapter; import java.util.ArrayList; impo

Java基础学习第二十五天——多线程学习总结(二)

文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 2016.03.31 lutianfei none JDK5中Lock锁的使用 虽然我们可以理解同步代码块和同步方法的锁对象问题,但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock. Lock: void lock(): 获取锁. void unlock():释放锁. ReentrantLock是Lock的实现类. public class SellT