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. ueditor使用中的坑

    项目中要使用富文本编辑于是采用了百度的开源富文本编辑器 ueditor    官网 http://ueditor.baidu.com/website/ 使用方法就按照官方的来的. 经过使用记录以下要点 ...

  2. LINQ to XML学习笔记

    一.XML基础知识 1.XML:可扩展标记语言 Extensible Markup Language ,提供了一种保存数据的格式,数据可以通过这种格式很容易地在不同的应用程序之间实现共享. 2.使用X ...

  3. linux工作队列

    工作队列一般用来做滞后的工作,比如在中断里面要做很多事,但是比较耗时,这时就可以把耗时的工作放到工作队列.说白了就是系统延时调度的一个自定义函数. 工作队列是实现延迟的新机制,从 2.5 版本 Lin ...

  4. 【BZOJ 3171】 [Tjoi2013]循环格

    Description 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0).给定一个起始位置(r,c) ,你可以沿着箭头防线在格 ...

  5. python学习笔记13(模块、包)

    在Python中有一个概念叫做模块(module),比如在Python中要调用sqrt函数,必须用import关键字引入math这个模块,下面就来了解一下Python中的模块. 模块文件以.py后缀结 ...

  6. 使用 Android Studio 跑新浪微博SDK Demo遇到的问题及解决

    概述 这是新浪微博官方 Android SDK Demo 使用 Android Studio 导入.编译并运行通过的版本. 源码:WeiboSdkDemo 官方项目请点击: weibo_android ...

  7. MapperScannerConfigurer(转)

    转:http://blog.csdn.net/ranmudaofa/article/details/8508028 原文:http://www.cnblogs.com/daxin/p/3545040. ...

  8. spoj 665

    直接判  没什么算法  也没什么技巧  水水~~ #include <cstdio> #include <cstring> #include <algorithm> ...

  9. spoj 62

    看了题解  自己好水   ...... #include <cstdio> #include <cstdlib> struct node { int x,y; }; node ...

  10. 发现一个可以在线运行JS代码的网站

    平时可以在这里玩 http://jsbin.com/