多线程程序设计学习(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思考
--->
四进阶说明
--->

 

读写锁

 1 package com.yeepay.sxf.thread6;
 2 /**
 3  * 读写锁
 4  * @author sxf
 5  *
 6  * 为了多线线程环境下保护数据安全,我们必须避免的冲突
 7  * 一个线程读取,另一个线程写入的read-write conflick
 8  * 一个线程写入,另一个线程写入的write-write conflick
 9  * 一个线程读取,另一个线程也在读取不会产生冲突
10  *
11  * 当线程想要获取读取锁定时:
12  *         -->已经有线程在执行写入,则等待。不等待,则发生read-write conflick
13  *         -->已经有线程在读取,则不需要等待。不存在read-read conflick
14  *
15  * 当线程想要获取写入锁定时:
16  *         -->已经有线程在执行写入,则等待。不等待,则发生write-write conflick
17  *         -->已经有线程在执行读取,则等待。不等待,则发生read-write conflick
18  *
19  */
20 public class ReadWriteLock {
21         //正在读取的线程个数
22         private Integer readInteger=0;
23         //正在写入的线程个数(最大值为1)
24         private Integer writeInteger=0;
25         //正在等待获取写入锁定的线程个数
26         private Integer writeWaitInteger=0;
27         //获取写入锁定优先的话,为true
28         private boolean writeBoolean=false;
29
30         //获取读取锁的方法
31         public synchronized void readLock() throws InterruptedException{
32             //如果有写入操作  ||写入优先并且存在等待写入的线程    则    读取线程等待
33             while(writeInteger>0||(writeBoolean&&writeWaitInteger>0)){
34                 wait();
35             }
36             //读取线程加1
37             readInteger++;
38         }
39         //释放读取锁定的方法
40         public synchronized void readUnLock(){
41             //读取减一
42             readInteger--;
43             //将写入设置优先
44             writeBoolean=true;
45             //唤醒所有线程
46             notifyAll();
47         }
48
49         //获取写入锁定
50         public synchronized void writeLock() throws InterruptedException{
51             //等待写入线程数量+1
52             writeWaitInteger++;
53             try {
54                 //如果有读取线程或写入线程,则等待
55                 while (readInteger>0||writeInteger>0) {
56                     wait();
57                 }
58             }finally{
59                 //执行到这,等待线程-1
60                 writeWaitInteger--;
61             }
62             //写入线程数+1
63             writeInteger++;
64         }
65
66
67         //释放写入锁定
68         public synchronized void  writeUnLock(){
69             //写入线程数-1
70             writeInteger--;
71             //写入的优先级去掉
72             writeBoolean=false;
73             //唤醒其他线程
74             notifyAll();
75         }
76
77 }

View Code

数据类(公共资源)

 1 package com.yeepay.sxf.thread6;
 2 /**
 3  * 数据类
 4  * 持有公共数据+该公共数据的读写锁
 5  * @author sxf
 6  *
 7  */
 8 public class Data {
 9     //数据类持有的锁
10     private final ReadWriteLock lock=new ReadWriteLock();
11     //要访问的公共数据
12     private final String[] buffer;
13     //构造器
14     public Data(int i){
15         buffer=new String[i];
16         for(int a=0;a<buffer.length;a++){
17             buffer[a]="**";
18         }
19     }
20     //读取数据的方法
21     public  String[] read() throws InterruptedException{
22         //获取读取锁定
23         lock.readLock();
24         try {
25             //模拟读用了1秒
26             Thread.sleep(1000);
27             return doRead();
28         } finally{
29             //释放读取锁定
30             lock.readUnLock();
31         }
32
33     }
34     //真正的读取操作
35     private String[] doRead(){
36         return buffer;
37     }
38
39     //写入的操作
40     public void write(String a) throws InterruptedException{
41         //获取写入锁定
42         lock.writeLock();
43         try {
44             //模拟写用了3秒
45             Thread.sleep(1000);
46             doWrite(a);
47         }finally{
48             //释放写入锁定
49             lock.writeUnLock();
50         }
51
52     }
53
54     //真正的写操作
55     private void doWrite(String a){
56         for(int i=0;i<buffer.length;i++){
57             buffer[i]=a;
58         }
59     }
60
61 }

View Code

读线程

 1 package com.yeepay.sxf.thread6;
 2
 3 /**
 4  * 读线程
 5  * @author sxf
 6  *
 7  */
 8 public class ReadThread implements Runnable{
 9
10     private Data data;
11
12     //构造器
13     public ReadThread(Data data) {
14
15         this.data=data;
16     }
17     @Override
18     public void run() {
19         while (true) {
20                 try {
21                     String [] aStrings=data.read();
22                     System.out.println("["+Thread.currentThread().getName()+"] 读取数据为:"+aStrings[0]);
23                 } catch (InterruptedException e) {
24                     // TODO Auto-generated catch block
25                     e.printStackTrace();
26                 }
27         }
28
29     }
30
31
32 }

View Code

写线程

 1 package com.yeepay.sxf.thread6;
 2 /**
 3  * 写线程
 4  *  * @author sxf
 5  *
 6  */
 7 public class WriteThead implements Runnable {
 8     //数据
 9     private Data data;
10
11     //构造器
12     public  WriteThead(Data data) {
13         this.data=data;
14     }
15
16     @Override
17     public void run() {
18
19         while(true){
20             for(int a=0;a<100;a++){
21                 String name=Thread.currentThread().getName();
22                 System.out.println("【"+name+"】写入"+a+"*"+name.substring(name.length()-2));
23                 try {
24                     data.write(a+"*"+name.substring(name.length()-2));
25                 } catch (InterruptedException e) {
26                     // TODO Auto-generated catch block
27                     e.printStackTrace();
28                 }
29             }
30         }
31     }
32
33
34 }

View Code

测试类

 1 package com.yeepay.sxf.thread6;
 2 /**
 3  * 测试类
 4  * @author sxf
 5  *
 6  */
 7 public class Test {
 8
 9     public static void main(String[] args) {
10         //声明公共数据类
11         Data data=new Data(2);
12         //声明读取线程
13         Thread readThread1=new Thread(new ReadThread(data));
14         readThread1.setName("读取线程sxf");
15         Thread readThread2=new Thread(new ReadThread(data));
16         readThread2.setName("读取线程sxs");
17         Thread readThread3=new Thread(new ReadThread(data));
18         readThread3.setName("读取线程sxy");
19
20         //声明写入线程
21         Thread writeThread1=new Thread(new WriteThead(data));
22         writeThread1.setName("写入线程yk");
23         Thread writeThread2=new Thread(new WriteThead(data));
24         writeThread2.setName("写入线程shl");
25         Thread writeThread3=new Thread(new WriteThead(data));
26         writeThread3.setName("写入线程shj");
27
28         //开启线程
29         readThread1.start();
30         readThread2.start();
31         readThread3.start();
32
33         writeThread1.start();
34         writeThread2.start();
35         writeThread3.start();
36
37
38     }
39 }

View Code

打印结果

 

【写入线程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

 

时间: 2024-09-30 22:57:11

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

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

Immutable pattern[坚不可摧模式] 一:immutable pattern的参与者--->immutable(不变的)参与者        1.1:immutable参与者是一个字段的值都无法更改的类.        1.2:immutable也没有任何用来更改字段值的方法.        1.3:immutable参与者方法不需要设置synchronized 二:immutable pattern模式什么时候使用--->当实例产生后,状态不再变化时        2.1实例状

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

Future pattern[订单取货模式] 一:Future pattern的参与者--->Client(客户需求)--->Host(蛋糕门店)--->Data(票据和蛋糕的接口)--->Future(蛋糕票据)--->ReaData(制作蛋糕过程)        二:Future pattern模式什么时候使用---> 三:Future pattern思考       ---> 四进阶说明        ---> 数据类接口 1 package com.

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

Worker pattern[工作模式]一:Worker pattern的参与者--->Client(委托人线程)--->Channel(通道,里边有,存放请求的队列)--->Request(工作内容的包装)--->Worker(工人线程)        二:Worker pattern模式什么时候使用--->类似生产者消费者 三:Worker pattern思考 四进阶说明--->工作线程取出请求内容包装后,根据多态,不同的请求执行不同的业务方法   Request接

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

Single Threaded Execution Pattern[独木桥模式] 一:single threaded execution pattern的参与者--->SharedResource(共享资源) 二:single threaded execution pattern模式什么时候使用--->多线程程序设计时--->数据可被多个线程访问的时候--->共享资源状态可能变化的时候--->需要确保数据安全性的时候 三:single threaded execution p

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

Thread-Specific-Storage[线程保管箱] 一:Thread-Specific Storage的参与者--->记录日志的线程(ClientThread)--->负责获取不同线程记录日志(Log)--->负责将日志写入文件的类(TsLog)         二:Thread-Specific Storage模式什么时候使用--->当每个线程必须有自己的独有信息时,可以将该信息放入线程保管箱ThreadLocal 三:Thread-Specific Storage思考

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

Active Object[接收异步消息的对象] 一:Active Object的参与者--->客户端线程(发起某种操作请求处理)--->代理角色(工头)--->实际执行者(工人)--->主动对象接口(工人和工头)--->生产端线程(加工产品的线程)--->存放生产请求的队列(存放请求的队列)--->请求实例化(将方法的启动和执行分离的实例化包含)--->订单--->产品--->订单产品的共同接口        二:Active Object模式

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

Producer-Consumer[生产消费者模式]一:Producer-Consumer pattern的参与者--->产品(蛋糕)--->通道(传递蛋糕的桌子)--->生产者线程(制造蛋糕的线程)--->消费者线程(吃掉蛋糕的线程)         二:Producer-Consumer pattern模式什么时候使用--->大量生产+大量消费的模式 三:Producer-Consumer pattern思考--->[生产消费者模式],肩负保护数据安全性使命的是通道

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

Balking[返回模式]timed[超时模式]一:balking pattern的参与者--->GuardedObject(被警戒的对象) --->该模式的角色:模拟修改警戒对象的线程,当警戒条件达到执行具体操作的线程,参与者(被警戒的参与者)        二:balking pattern模式什么时候使用--->不需要刻意去执行什么操作的时候(比如说自动保存)--->不想等待警戒条件成立时.(不让线程休息)--->警戒条件只有第一次成立时候.    三:balking

多线程程序设计学习(4)guarded suspension模式

Guarded Suspension[生产消费者模式] 一:guarded suspension的参与者--->guardedObject(被防卫)参与者                1.1该参与者拥有一个被防卫的方法(getRequest),如果警戒条件达成,则执行.警戒条件不达成,则线程进入wait set                1.2该参与者还拥有一个改变参与者状态的方法(putRequest).参与者的状态影响着警戒条件的是否达成. --->该模式的角色:生产端线程,消费端线