在上文中提到了Lock接口以及对象使用它很优雅的控制了竞争资源的安全访问但是这种锁不区分读写称这种锁为普通锁为了提高性能Java提供了读写锁在读的地方使用读锁在写的地方使用写锁灵活控制在一定程度上提高了程序的执行效率
Java中读写锁有个接口ncurrentlocksReadWriteLock也有具体的实现ReentrantReadWriteLock详细的API可以查看JavaAPI文档
下面这个例子是在文例子的基础上将普通锁改为读写锁并添加账户余额查询的功能代码如下
import ncurrentExecutorService;
import ncurrentExecutors;
import ncurrentlocksReadWriteLock;
import ncurrentlocksReentrantReadWriteLock;
/**
* Java线程锁
*
* @author leizhimin ::
*/
public class Test {
public static void main(String[] args) {
//创建并发访问的账户
MyCount myCount = new MyCount( );
//创建一个锁对象
ReadWriteLock lock = new ReentrantReadWriteLock(false);
//创建一个线程池
ExecutorService pool = ExecutorsnewFixedThreadPool();
//创建一些并发访问用户一个信用卡存的存取的取好热闹啊
User u = new User(张三 myCount lock false);
User u = new User(张三他爹 myCount lock false);
User u = new User(张三他弟 myCount lock false);
User u = new User(张三 myCount lock false);
User u = new User(张三他爹 myCount lock true);
//在线程池中执行各个用户的操作
poolexecute(u);
poolexecute(u);
poolexecute(u);
poolexecute(u);
poolexecute(u);
//关闭线程池
poolshutdown();
}
}
/**
* 信用卡的用户
*/
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) {
thisname = name;
thismyCount = myCount;
thisiocash = iocash;
thismyLock = myLock;
thisischeck = ischeck;
}
public void run() {
if (ischeck) {
//获取读锁
myLockreadLock()lock();
Systemoutprintln(读 + name + 正在查询 + myCount + 账户当前金额为 + myCountgetCash());
//释放读锁
myLockreadLock()unlock();
} else {
//获取写锁
myLockwriteLock()lock();
//执行现金业务
Systemoutprintln(写 + name + 正在操作 + myCount + 账户金额为 + iocash + 当前金额为 + myCountgetCash());
myCountsetCash(myCountgetCash() + iocash);
Systemoutprintln(写 + name + 操作 + myCount + 账户成功金额为 + iocash + 当前金额为 + myCountgetCash());
//释放写锁
myLockwriteLock()unlock();
}
}
}
/**
* 信用卡账户可随意透支
*/
class MyCount {
private String oid; //账号
private int cash; //账户余额
MyCount(String oid int cash) {
thisoid = oid;
thiscash = cash;
}
public String getOid() {
return oid;
}
public void setOid(String oid) {
thisoid = oid;
}
public int getCash() {
return cash;
}
public void setCash(int cash) {
thiscash = cash;
}
@Override
public String toString() {
return MyCount{ +
oid= + oid + \ +
cash= + cash +
};
}
}
写张三正在操作MyCount{oid= cash=}账户金额为当前金额为
写张三操作MyCount{oid= cash=}账户成功金额为当前金额为
写张三他弟正在操作MyCount{oid= cash=}账户金额为当前金额为
写张三他弟操作MyCount{oid= cash=}账户成功金额为当前金额为
写张三正在操作MyCount{oid= cash=}账户金额为当前金额为
写张三操作MyCount{oid= cash=}账户成功金额为当前金额为
读张三他爹正在查询MyCount{oid= cash=}账户当前金额为
写张三他爹正在操作MyCount{oid= cash=}账户金额为当前金额为
写张三他爹操作MyCount{oid= cash=}账户成功金额为当前金额为
Process finished with exit code
在实际开发中最好在能用读写锁的情况下使用读写锁而不要用普通锁以求更好的性能