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. Mysql 如何删除数据表中的重复数据!

    1.使用distinct查询所有不重复的记录 2.创建数据表相同结构的临时表,将第一步的数据复制进去 create temporary table if not exists student_temp ...

  2. 【Entity Framework】初级篇--ObjectContext、ObjectQuery、ObjectStateEntry、ObjectStateManager类的介绍

    本节,简单的介绍EF中的ObjectContext.ObjectQuery.ObjectStateEntry.ObjectStateManager这个几个比较重要的类,它们都位于System.Data ...

  3. Tesseract初探

    一.框架介绍 Tesseract 是一款图片识别工具,可以抓取图片中的文字,可以支持多种语言(默认是英语),需要下载开源文件可以在github上下载,如果知识应用不想太多深究直接在google cod ...

  4. 懒惰的JY--关于遍历

    先上题: [问题描述] 众所周知,JY的百度搜索算法已经练的炉火纯青,任何搜索题都能0.000ms出解. 不幸的是,JY遇到了一道百度搜索算法解决不了的题目,题目是这样的: 给定N个数A[1] A[2 ...

  5. iOS 的 Gif 渲染引擎 FLAnimatedImage-b

    公司的项目有个首页加载一张2M左右的git图,刚做的时候是使用的SDWebImage里面的方法: + (UIImage *)sd_animatedGIFNamed:(NSString *)name; ...

  6. PD 脚本中列名注释用Name属性

    操作步骤:Database=>Generate Datatabase=>Format选项卡=>勾选 Generate name in empty comment项

  7. 字符串截取 方法 String b=a.substring(0, a.indexOf("乘坐"));

    String b=a.substring(0, a.indexOf("乘坐"));

  8. 6779. Can you answer these queries VII - SPOJ

    Given a tree with N ( N<=100000 ) nodes. Each node has a interger value x_i ( |x_i|<=10000 ). ...

  9. bzoj 1242: Zju1015 Fishing Net 弦图判定

    1242: Zju1015 Fishing Net弦图判定 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 214  Solved: 81[Submit ...

  10. 解决WIN8 磁盘100 活动占用100% win8硬盘一直响

    一.先看最终效果: 二.再说解决办法:   1.任务管理器关闭进程 taskhost.exe和类似于taskhostxx.exe开头的进程. 2.在电源管理里面设置2分钟不使用硬盘则关闭硬盘,看我的截 ...