锁所提供的最重要的改进之一就是ReadWriteLock接口和唯一 一个实现它的ReentrantReadWriteLock类。这个类提供两把锁,一把用于读操作和一把用于写操作。同时可以有多个线程执行读操作,但只有一个线程可以执行写操作。当一个线程正在执行一个写操作,不可能有任何线程执行读操作。

参考http://ifeve.com/basic-thread-synchronization-6/#more-7030 做了优化的例子
创建了5个读线程、一个写线程,分别读10次、写3次

PricesInfo

package threadTest.reentrantReadWriteLockTest;

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() {
this.price1 = 1.0;
this.price2 = 2.0;
this.lock = new ReentrantReadWriteLock();
} public double getPrice1() {
lock.readLock().lock();
System.out.printf("%s : Price1 开始读了!\n" ,Thread.currentThread().getName());
double value = price1;
System.out.printf("%s : Price1 读取完毕 : %f\n"
,Thread.currentThread().getName(),value);
lock.readLock().unlock();
return value;
} public double getPrice2() {
lock.readLock().lock();
System.out.printf("%s : Price2开始读了!\n" ,Thread.currentThread().getName());
double value = price2;
System.out.printf("%s : Price2读取完毕 : %f\n"
,Thread.currentThread().getName(),value);
lock.readLock().unlock();
return value;
} public void setPrices(double price1, double price2) {
lock.writeLock().lock();
System.out.printf("Writer:Attempt to modify the price.\n");
this.price2 = price2;
this.price1 = price1; System.out.printf("Writer:Prices have been modified.\n");
lock.writeLock().unlock(); } }
Reader
package threadTest.reentrantReadWriteLockTest;

public class Reader implements Runnable {
private PricesInfo priceInfo; public Reader(PricesInfo priceInfo) {
this.priceInfo = priceInfo;
} @Override
public void run() {
for (int i = 0; i < 10; i++) {
priceInfo.getPrice1();
priceInfo.getPrice2();
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

Writer

package threadTest.reentrantReadWriteLockTest;

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++) {
pricesInfo.setPrices((i+1)* 10, (i+1) * 100);
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

main函数

package threadTest.reentrantReadWriteLockTest;

public class App1 {
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();
}
}

结果如下

使用ReentrantReadWriteLock,同时可以有多个线程执行读操作,但只有一个线程可以执行写操作

ReentrantReadWriteLock锁例子的更多相关文章

  1. 缓存中使用的ReentrantReadWriteLock锁

    java中提供了lock锁,简便了设计缓存,下面程序主要是使用读写锁的应用.... import java.util.HashMap; import java.util.Map; import jav ...

  2. Java多线程可重入锁例子解析

    “可重入锁”的概念是:自己可以再次获得自己的内部锁.比如有一条线程获得了某个对象的锁,此时这个对象还没有释放,当其再次想获得这个对象的锁的时候还是可以获得的,如果不可锁重入的话,就会造成死锁. cla ...

  3. java并发编程 | 锁详解:AQS,Lock,ReentrantLock,ReentrantReadWriteLock

    原文:java并发编程 | 锁详解:AQS,Lock,ReentrantLock,ReentrantReadWriteLock 锁 锁是用来控制多个线程访问共享资源的方式,java中可以使用synch ...

  4. java锁类型

    转载链接在每个锁类型后边 线程锁类型 1.自旋锁 ,自旋,jvm默认是10次吧,有jvm自己控制.for去争取锁 锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchroni ...

  5. 05 JDK1.5 Lock锁

    一.synchronized的再次讨论 使用synchronized关键字来标记一个方法或者代码块,当某个线程调用该对象的synchronized方法或者访问synchronized代码块时, 这个线 ...

  6. Java并发--lock锁详解

    在上一篇文章中我们讲到了如何使用关键字synchronized来实现同步访问.本文我们继续来探讨这个问题,从Java 5之后,在java.util.concurrent.locks包下提供了另外一种方 ...

  7. Java并发处理锁 Lock

    在上一篇文章中我们讲到了如何使用关键字synchronized来实现同步访问.本文我们继续来探讨这个问题,从Java 5之后,在 java.util.concurrent.locks 包下提供了另外一 ...

  8. 搞定ReentrantReadWriteLock 几道小小数学题就够了

    | 好看请赞,养成习惯 你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it ...

  9. 史上最全java里面的锁

    什么是锁 在计算机科学中,锁(lock)或互斥(mutex)是一种同步机制,用于在有许多执行线程的环境中强制对资源的访问限制.锁旨在强制实施互斥排他.并发控制策略. 锁通常需要硬件支持才能有效实施.这 ...

随机推荐

  1. JavaScript中的闭包(closure)

    闭包的特性 1.函数嵌套函数 2.函数内部可以引用外部的参数和变量 3.参数和变量不会被垃圾回收机制回收  闭包的缺点就是常驻内存,会增大内存使用量,使用不当很容易造成内存泄露,主要用于私有的方法和变 ...

  2. HDUOJ-----2824The Euler function

    The Euler function Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  3. HDUOJ-----1066Last non-zero Digit in N!

    Last non-zero Digit in N! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Jav ...

  4. HDUOJ-------Being a Good Boy in Spring Festival

    Being a Good Boy in Spring Festival Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32 ...

  5. Linux卸载NAS磁盘,报device is busy

    # umount /data umount.nfs: /data: device is busy umount.nfs: /data: device is busy # fuser -m -v /da ...

  6. __attribute__中constructor和destructor

    1.前言 最近看到一份代码,看到一个函数前面用__attribute__((destructor))修饰,当时感觉有点怪怪的,搜了整个程序,也没发现哪个地方调用这个函数.于是从字面意思猜想,该函数会在 ...

  7. Android性能优化之被忽视的Memory Leaks

    起因 写博客就像讲故事.得有起因,经过,结果,人物.地点和时间.今天就容我给大家讲一个故事. 人物呢.肯定是我了. 故事则发生在近期的这两天,地点在coder君上班的公司.那天无意中我发现了一个奇怪的 ...

  8. 找到当前mysql group replication 环境的primary结点

    一.起原: mysql group replication 有两种模式.第一种是single primary 也就是说单个primary .这个模式下只有这一个主可以写入: 第二种是multi pri ...

  9. Spring Cloud构建微服务架构(三)断路器

    在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待.这样就不会使得线程因 ...

  10. C#匿名对象的使用

    单个对象 new { Inv = item.Inv, Count = item.Count } 数组 var testData = new[] { }, }, }, }, }, }, }, }, } ...