Read-Write Lock Pattern【读写】
一:Read-Write Lock Pattern的参与者
--->读写锁
--->数据(共享资源)
--->读线程
--->写线程

二Read-Write Lock Pattern模式什么时候使用
--->
 * 为了多线线程环境下保护数据安全,我们必须避免的冲突
 * 一个线程读取,另一个线程写入的read-write conflick
 * 一个线程写入,另一个线程写入的write-write conflick
 * 一个线程读取,另一个线程也在读取不会产生冲突
 *
 * 当线程想要获取读取锁定时:
 * -->已经有线程在执行写入,则等待。不等待,则发生read-write conflick
 * -->已经有线程在读取,则不需要等待。不存在read-read conflick
 *
 * 当线程想要获取写入锁定时:
 * -->已经有线程在执行写入,则等待。不等待,则发生write-write conflick
 * -->已经有线程在执行读取,则等待。不等待,则发生read-write conflick

--->利用同时(读取)不会引起数据冲突的特性,提高系统的性能
--->适合读取操作繁重时
--->适合读取操作比写入操作繁重时

三:Read-Write Lock Pattern思考
--->
四进阶说明
--->

读写锁

 package com.yeepay.sxf.thread6;
/**
* 读写锁
* @author sxf
*
* 为了多线线程环境下保护数据安全,我们必须避免的冲突
* 一个线程读取,另一个线程写入的read-write conflick
* 一个线程写入,另一个线程写入的write-write conflick
* 一个线程读取,另一个线程也在读取不会产生冲突
*
* 当线程想要获取读取锁定时:
* -->已经有线程在执行写入,则等待。不等待,则发生read-write conflick
* -->已经有线程在读取,则不需要等待。不存在read-read conflick
*
* 当线程想要获取写入锁定时:
* -->已经有线程在执行写入,则等待。不等待,则发生write-write conflick
* -->已经有线程在执行读取,则等待。不等待,则发生read-write conflick
*
*/
public class ReadWriteLock {
//正在读取的线程个数
private Integer readInteger=0;
//正在写入的线程个数(最大值为1)
private Integer writeInteger=0;
//正在等待获取写入锁定的线程个数
private Integer writeWaitInteger=0;
//获取写入锁定优先的话,为true
private boolean writeBoolean=false; //获取读取锁的方法
public synchronized void readLock() throws InterruptedException{
//如果有写入操作 ||写入优先并且存在等待写入的线程 则 读取线程等待
while(writeInteger>0||(writeBoolean&&writeWaitInteger>0)){
wait();
}
//读取线程加1
readInteger++;
}
//释放读取锁定的方法
public synchronized void readUnLock(){
//读取减一
readInteger--;
//将写入设置优先
writeBoolean=true;
//唤醒所有线程
notifyAll();
} //获取写入锁定
public synchronized void writeLock() throws InterruptedException{
//等待写入线程数量+1
writeWaitInteger++;
try {
//如果有读取线程或写入线程,则等待
while (readInteger>0||writeInteger>0) {
wait();
}
}finally{
//执行到这,等待线程-1
writeWaitInteger--;
}
//写入线程数+1
writeInteger++;
} //释放写入锁定
public synchronized void writeUnLock(){
//写入线程数-1
writeInteger--;
//写入的优先级去掉
writeBoolean=false;
//唤醒其他线程
notifyAll();
} }

数据类(公共资源)

 package com.yeepay.sxf.thread6;
/**
* 数据类
* 持有公共数据+该公共数据的读写锁
* @author sxf
*
*/
public class Data {
//数据类持有的锁
private final ReadWriteLock lock=new ReadWriteLock();
//要访问的公共数据
private final String[] buffer;
//构造器
public Data(int i){
buffer=new String[i];
for(int a=0;a<buffer.length;a++){
buffer[a]="**";
}
}
//读取数据的方法
public String[] read() throws InterruptedException{
//获取读取锁定
lock.readLock();
try {
//模拟读用了1秒
Thread.sleep(1000);
return doRead();
} finally{
//释放读取锁定
lock.readUnLock();
} }
//真正的读取操作
private String[] doRead(){
return buffer;
} //写入的操作
public void write(String a) throws InterruptedException{
//获取写入锁定
lock.writeLock();
try {
//模拟写用了3秒
Thread.sleep(1000);
doWrite(a);
}finally{
//释放写入锁定
lock.writeUnLock();
} } //真正的写操作
private void doWrite(String a){
for(int i=0;i<buffer.length;i++){
buffer[i]=a;
}
} }

读线程

 package com.yeepay.sxf.thread6;

 /**
* 读线程
* @author sxf
*
*/
public class ReadThread implements Runnable{ private Data data; //构造器
public ReadThread(Data data) { this.data=data;
}
@Override
public void run() {
while (true) {
try {
String [] aStrings=data.read();
System.out.println("["+Thread.currentThread().getName()+"] 读取数据为:"+aStrings[0]);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} } }

写线程

 package com.yeepay.sxf.thread6;
/**
* 写线程
* * @author sxf
*
*/
public class WriteThead implements Runnable {
//数据
private Data data; //构造器
public WriteThead(Data data) {
this.data=data;
} @Override
public void run() { while(true){
for(int a=0;a<100;a++){
String name=Thread.currentThread().getName();
System.out.println("【"+name+"】写入"+a+"*"+name.substring(name.length()-2));
try {
data.write(a+"*"+name.substring(name.length()-2));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} }

测试类

 package com.yeepay.sxf.thread6;
/**
* 测试类
* @author sxf
*
*/
public class Test { public static void main(String[] args) {
//声明公共数据类
Data data=new Data(2);
//声明读取线程
Thread readThread1=new Thread(new ReadThread(data));
readThread1.setName("读取线程sxf");
Thread readThread2=new Thread(new ReadThread(data));
readThread2.setName("读取线程sxs");
Thread readThread3=new Thread(new ReadThread(data));
readThread3.setName("读取线程sxy"); //声明写入线程
Thread writeThread1=new Thread(new WriteThead(data));
writeThread1.setName("写入线程yk");
Thread writeThread2=new Thread(new WriteThead(data));
writeThread2.setName("写入线程shl");
Thread writeThread3=new Thread(new WriteThead(data));
writeThread3.setName("写入线程shj"); //开启线程
readThread1.start();
readThread2.start();
readThread3.start(); writeThread1.start();
writeThread2.start();
writeThread3.start(); }
}

打印结果

【写入线程yk】写入0*yk
【写入线程shj】写入0*hj
【写入线程shl】写入0*hl
[读取线程sxf] 读取数据为:**
[读取线程sxy] 读取数据为:**
[读取线程sxs] 读取数据为:**
【写入线程shj】写入1*hj
[读取线程sxs] 读取数据为:0*hj
[读取线程sxy] 读取数据为:0*hj
[读取线程sxf] 读取数据为:0*hj
【写入线程shj】写入2*hj
[读取线程sxf] 读取数据为:1*hj
[读取线程sxy] 读取数据为:1*hj
[读取线程sxs] 读取数据为:1*hj
【写入线程shl】写入1*hl
【写入线程shj】写入3*hj
【写入线程shl】写入2*hl
【写入线程shj】写入4*hj
【写入线程shl】写入3*hl
【写入线程shj】写入5*hj
【写入线程shl】写入4*hl

多线程程序设计学习(7)read-write lock pattern的更多相关文章

  1. 多线程程序设计学习(3)immutable pattern模式

    Immutable pattern[坚不可摧模式] 一:immutable pattern的参与者--->immutable(不变的)参与者        1.1:immutable参与者是一个 ...

  2. 多线程程序设计学习(10)Future pattern

    Future pattern[订单取货模式] 一:Future pattern的参与者--->Client(客户需求)--->Host(蛋糕门店)--->Data(票据和蛋糕的接口) ...

  3. 多线程程序设计学习(9)worker pattern模式

    Worker pattern[工作模式]一:Worker pattern的参与者--->Client(委托人线程)--->Channel(通道,里边有,存放请求的队列)--->Req ...

  4. 多线程程序设计学习(11)Two-phapse-Termination pattern

    Two-phapse-Termination[A终止B线程] 一:Two-phapse-Termination的参与者--->A线程--->B线程 二:Two-phapse-Termina ...

  5. 多线程程序设计学习(2)之single threaded execution pattern

    Single Threaded Execution Pattern[独木桥模式] 一:single threaded execution pattern的参与者--->SharedResourc ...

  6. 多线程程序设计学习(13)Active Object pattern

    Active Object[接收异步消息的对象] 一:Active Object的参与者--->客户端线程(发起某种操作请求处理)--->代理角色(工头)--->实际执行者(工人)- ...

  7. 多线程程序设计学习(12)Thread-soecific storage pattern

    Thread-Specific-Storage[线程保管箱] 一:Thread-Specific Storage的参与者--->记录日志的线程(ClientThread)--->负责获取不 ...

  8. 多线程程序设计学习(6)Producer-Consumer模式

    Producer-Consumer[生产消费者模式]一:Producer-Consumer pattern的参与者--->产品(蛋糕)--->通道(传递蛋糕的桌子)--->生产者线程 ...

  9. 多线程程序设计学习(5)balking模式和timed模式

    Balking[返回模式]timed[超时模式]一:balking pattern的参与者--->GuardedObject(被警戒的对象) --->该模式的角色:模拟修改警戒对象的线程, ...

随机推荐

  1. linux set,env和export

    set,env和export这三个命令都可以用来显示shell变量 set 显示当前shell的变量,包括当前用户的变量 env 显示当前用户的变量 export 显示当前导出成用户变量的shell变 ...

  2. UVA 725

    Description   Write a program that finds and displays all pairs of 5-digit numbers that between them ...

  3. jdbc mysql 取数,突然取不到数据,数据库中有数据

    项目用的是jdbc+mysql,局网取数据的时候,数据一切正常,但是传到服务器上以后,曾经是好的 不知道为什么,近期一传就取不到数据,发现android写的也没有问题,至少大体上没有语法问题. 跟踪后 ...

  4. 创建dblink 同义词

     database link dblink的主要作用是两个数据库间的数据访问 create database link my_test connect to testdbname identified ...

  5. 因程序问题引起的服务器CPU负荷一直保持在90%以上

    昨天早上刚到办公室,就接到客户的电话说其某台小型机的CPU负荷一直保持在90以上,告警短信发个不停,一直没有间断过.该服务器是一台IBM的小型机,性能应该还是不错的,出现这样的情况确实不太正常.登陆上 ...

  6. 汽车之家, 比亚迪等成为开源数据库SSDB的用户

    开源的 NoSQL 数据库 SSDB 已经一岁多了! 在这一年中, SSDB 不断被应用在众多业界知名互联网企业, 创业团队的产品中. 最近, 比亚迪汽车也成为 SSDB 的用户, 其将 SSDB 作 ...

  7. springmvc+json

    1.在写我的springmvc demo时,由于要向前台返回相关信息,于是设置了@ResponseBody,但是要把对象转换成json格式,我却没有在xml文件里配置,所以报如下错误:HttpMedi ...

  8. 山东省第四届ACM大学生程序设计竞赛解题报告(部分)

    2013年"浪潮杯"山东省第四届ACM大学生程序设计竞赛排名:http://acm.upc.edu.cn/ranklist/ 一.第J题坑爹大水题,模拟一下就行了 J:Contes ...

  9. 1031: [JSOI2007]字符加密Cipher - BZOJ

    Description喜欢钻研问题的JS 同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法:把需要加密的信息排成一圈,显然,它们有很多种不同的读法.例如下图,可以读作: ...

  10. 使用Flexbox实现CSS竖向居中

    竖向居中需要一个父元素和一个子元素合作完成. <div class="flexbox-container"> <div>Blah blah</div& ...