ReadWriteLock

2 篇文章 0 订阅

转载:http://www.cnblogs.com/tankaixiong/p/3772502.html

为了提高性能,Java提供了读写锁,在读的地方使用读锁,在写的地方使用写锁,灵活控制,如果没有写锁的情况下,读是无阻塞的,在一定程度上提高了程序的执行效率。

Java中读写锁有个接口java.util.concurrent.locks.ReadWriteLock,也有具体的实现ReentrantReadWriteLock,详细的API可以查看JavaAPI文档。

ReentrantReadWriteLock 和 ReentrantLock 不是继承关系,但都是基于 AbstractQueuedSynchronizer 来实现。

lock方法 是基于CAS 来实现的

注意: 在同一线程中,持有读锁后,不能直接调用写锁的lock方法 ,否则会造成死锁。

下面这个例子是在文例子的基础上,将普通锁改为读写锁,并添加账户余额查询的功能,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import  java.util.concurrent.ExecutorService;
import  java.util.concurrent.Executors;
import  java.util.concurrent.locks.ReadWriteLock;
import  java.util.concurrent.locks.ReentrantReadWriteLock;
 
/**
public  class  Test {
          public  static  void  main(String[] args) {
                  //创建并发访问的账户
                  MyCount myCount =  new  MyCount( "95599200901215522" 10000 );
                  //创建一个锁对象
                  ReadWriteLock lock =  new  ReentrantReadWriteLock( false );
                  //创建一个线程池
                  ExecutorService pool = Executors.newFixedThreadPool( 2 );
                  //创建一些并发访问用户,一个信用卡,存的存,取的取,好热闹啊
                  User u1 =  new  User( "张三" , myCount, - 4000 , lock,  false );
                  User u2 =  new  User( "张三他爹" , myCount,  6000 , lock,  false );
                  User u3 =  new  User( "张三他弟" , myCount, - 8000 , lock,  false );
                  User u4 =  new  User( "张三" , myCount,  800 , lock,  false );
                  User u5 =  new  User( "张三他爹" , myCount,  0 , lock,  true );
                  //在线程池中执行各个用户的操作
                  pool.execute(u1);
                  pool.execute(u2);
                  pool.execute(u3);
                  pool.execute(u4);
                  pool.execute(u5);
                  //关闭线程池
                  pool.shutdown();
          }
}
 
/**
class  User  implements  Runnable {
          private  String name;                  //用户名
          private  MyCount myCount;          //所要操作的账户
          private  int  iocash;                  //操作的金额,当然有正负之分了
          private  ReadWriteLock myLock;                  //执行操作所需的锁对象
          private  boolean  ischeck;          //是否查询
 
          User(String name, MyCount myCount,  int  iocash, ReadWriteLock myLock,  boolean  ischeck) {
                  this .name = name;
                  this .myCount = myCount;
                  this .iocash = iocash;
                  this .myLock = myLock;
                  this .ischeck = ischeck;
          }
 
          public  void  run() {
                  if  (ischeck) {
                          //获取读锁
                          myLock.readLock().lock();
                          System.out.println( "读:"  + name +  "正在查询"  + myCount +  "账户,当前金额为"  + myCount.getCash());
                          //释放读锁
                          myLock.readLock().unlock();
                  else  {
                          //获取写锁
                          myLock.writeLock().lock();
                          //执行现金业务
                          System.out.println( "写:"  + name +  "正在操作"  + myCount +  "账户,金额为"  + iocash + ",当前金额为"  + myCount.getCash());
                          myCount.setCash(myCount.getCash() + iocash);
                          System.out.println( "写:"  + name +  "操作"  + myCount +  "账户成功,金额为"  + iocash + ",当前金额为"  + myCount.getCash());
                          //释放写锁
                          myLock.writeLock().unlock();
                  }
          }
}
 
/**
class  MyCount {
          private  String oid;          //账号
          private  int  cash;              //账户余额
 
          MyCount(String oid,  int  cash) {
                  this .oid = oid;
                  this .cash = cash;
          }
 
          public  String getOid() {
                  return  oid;
          }
 
          public  void  setOid(String oid) {
                  this .oid = oid;
          }
 
          public  int  getCash() {
                  return  cash;
          }
 
          public  void  setCash( int  cash) {
                  this .cash = cash;
          }
 
          @Override
          public  String toString() {
                  return  "MyCount{"  +
                                  "oid='"  + oid + '\ ''  +
                                  ", cash="  + cash +
                                  '}' ;
          }
}
写:张三正在操作MyCount{oid= '95599200901215522' , cash= 10000 }账户,金额为- 4000 ,当前金额为 10000
写:张三操作MyCount{oid= '95599200901215522' , cash= 6000 }账户成功,金额为- 4000 ,当前金额为 6000
写:张三他弟正在操作MyCount{oid= '95599200901215522' , cash= 6000 }账户,金额为- 8000 ,当前金额为 6000
写:张三他弟操作MyCount{oid= '95599200901215522' , cash=- 2000 }账户成功,金额为- 8000 ,当前金额为- 2000
写:张三正在操作MyCount{oid= '95599200901215522' , cash=- 2000 }账户,金额为 800 ,当前金额为- 2000
写:张三操作MyCount{oid= '95599200901215522' , cash=- 1200 }账户成功,金额为 800 ,当前金额为- 1200
读:张三他爹正在查询MyCount{oid= '95599200901215522' , cash=- 1200 }账户,当前金额为- 1200
写:张三他爹正在操作MyCount{oid= '95599200901215522' , cash=- 1200 }账户,金额为 6000 ,当前金额为- 1200
写:张三他爹操作MyCount{oid= '95599200901215522' , cash= 4800 }账户成功,金额为 6000 ,当前金额为 4800
 
Process finished with exit code  0

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值