多线程程序设计学习(7)read-write lock pattern
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的更多相关文章
- 多线程程序设计学习(3)immutable pattern模式
Immutable pattern[坚不可摧模式] 一:immutable pattern的参与者--->immutable(不变的)参与者 1.1:immutable参与者是一个 ...
- 多线程程序设计学习(10)Future pattern
Future pattern[订单取货模式] 一:Future pattern的参与者--->Client(客户需求)--->Host(蛋糕门店)--->Data(票据和蛋糕的接口) ...
- 多线程程序设计学习(9)worker pattern模式
Worker pattern[工作模式]一:Worker pattern的参与者--->Client(委托人线程)--->Channel(通道,里边有,存放请求的队列)--->Req ...
- 多线程程序设计学习(11)Two-phapse-Termination pattern
Two-phapse-Termination[A终止B线程] 一:Two-phapse-Termination的参与者--->A线程--->B线程 二:Two-phapse-Termina ...
- 多线程程序设计学习(2)之single threaded execution pattern
Single Threaded Execution Pattern[独木桥模式] 一:single threaded execution pattern的参与者--->SharedResourc ...
- 多线程程序设计学习(13)Active Object pattern
Active Object[接收异步消息的对象] 一:Active Object的参与者--->客户端线程(发起某种操作请求处理)--->代理角色(工头)--->实际执行者(工人)- ...
- 多线程程序设计学习(12)Thread-soecific storage pattern
Thread-Specific-Storage[线程保管箱] 一:Thread-Specific Storage的参与者--->记录日志的线程(ClientThread)--->负责获取不 ...
- 多线程程序设计学习(6)Producer-Consumer模式
Producer-Consumer[生产消费者模式]一:Producer-Consumer pattern的参与者--->产品(蛋糕)--->通道(传递蛋糕的桌子)--->生产者线程 ...
- 多线程程序设计学习(5)balking模式和timed模式
Balking[返回模式]timed[超时模式]一:balking pattern的参与者--->GuardedObject(被警戒的对象) --->该模式的角色:模拟修改警戒对象的线程, ...
随机推荐
- WPF中的文字修饰
我们知道,文字的修饰包括:空心字.立体字.划线字.阴影字.加粗.倾斜等.这里只说划线字的修饰方式,按划线的位置,我们可将之分为:上划线.中划线.基线与下划线.如图: 从上至下,分别为上划线(Overl ...
- 程序使用嵌套的for循环找出2〜100中的素数
#import <Foundation/Foundation.h> int main () { /* local variable definition */ int i, j; ; i& ...
- C++ 虚函数表解析(转载)
转载自:陈皓 http://blog.csdn.net/haoel/article/details/1948051/ 前言 C++中的虚函数的作用主要是实现了多态的机制.关于多态,简而言之就是用父类型 ...
- iOS 基础 第四天(0809)
0809 - 内存管理,只对oc对象生效. alloc.retain.release.retainCount 局部变量是放在栈里面的,oc对象是放在堆里面的.栈里面的内容系统自动回收,而堆里面的内容还 ...
- iOS 10 的适配问题-b
随着iOS10发布的临近,大家的App都需要适配iOS10,下面是我总结的一些关于iOS10适配方面的问题,如果有错误,欢迎指出. 1.系统判断方法失效: 在你的项目中,当需要判断系统版本的话,不要使 ...
- play2 控制台打印乱码问题
修改 play安装目录下,framework/build.bat java -Xms512M -Xmx1024M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:Ma ...
- Linux中的MyEclipse配置Hadoop
一.所需软件 注意:安装MyEclipse后,我再已安装软件里找不到MyEclipse,所以我在root权限下用命令行启动MyEclipse,貌似避免了很多权限问题. sudo su 输入密码 cd ...
- [转载]Jquery Form插件表单参数
表单插件API提供了几个方法,让你轻松管理表单数据和进行表单提交. ajaxForm增 加所有需要的事件监听器,为AJAX提交表单做好准备.ajaxForm不能提交表单.在document的ready ...
- sublime 配置
Sublime Text 2是那种让人会一眼就爱上的编辑器,不仅GUI让人眼前一亮,功能更是没的说,拓展性目前来说也完全够用了,网上介绍软件的文章和推荐插件的文章也不少,而且很不错,大家可以去找找自己 ...
- 快速排序(quicksort)算法实现
快速排序(quicksort)是分治法的典型例子,它的主要思想是将一个待排序的数组以数组的某一个元素X为轴,使这个轴的左侧元素都比X大,而右侧元素都比X小(从大到小排序).然后以这个X在变换后数组的位 ...