ReentrantReadWriteLock
所谓的读写锁,是访问资源共享共享锁、互斥锁,如果对资源加了写锁,其他线程无法获取写锁与读锁,但是持有写锁的线程,可以对资源
加读锁;如果一个线程对资源加了读锁,那么其他线程可以继续加读锁。读读共享、读写互斥、写写互斥
package dmeo9;
public class MyAccount {
private String oid;
private int cash;
public MyAccount(){
}
public MyAccount(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;
}
}
package dmeo9;
import java.util.concurrent.locks.ReadWriteLock;
public class User implements Runnable {
private String name;//用户名
private MyAccount myAccount;//操作的账户
private int ioCash;//操作的金额
private ReadWriteLock readWriteLock;//读写锁操作锁需要的锁
private boolean isCheck;//是否操作?
public User() {
}
public User(String name, MyAccount myAccount, int ioCash, ReadWriteLock readWriteLock, boolean isCheck) {
this.name = name;
this.myAccount = myAccount;
this.ioCash = ioCash;
this.readWriteLock = readWriteLock;
this.isCheck = isCheck;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public MyAccount getMyAccount() {
return myAccount;
}
public void setMyAccount(MyAccount myAccount) {
this.myAccount = myAccount;
}
public int getIoCash() {
return ioCash;
}
public void setIoCash(int ioCash) {
this.ioCash = ioCash;
}
public ReadWriteLock getReadWriteLock() {
return readWriteLock;
}
public void setReadWriteLock(ReadWriteLock readWriteLock) {
this.readWriteLock = readWriteLock;
}
public boolean isCheck() {
return isCheck;
}
public void setCheck(boolean check) {
isCheck = check;
}
@Override
public void run() {
if (isCheck) {
/*获取读锁*/
try {
readWriteLock.readLock().lock();
System.err.println("\n读:" + getName() + "\t正在read 查询\t" + getMyAccount() + "\t账户,当前金额为:" + myAccount.getCash());
} catch (Exception e) {
e.printStackTrace();
} finally {
/*释放读锁*/
readWriteLock.readLock().unlock();
}
} else {
/*获取写的锁*/
try {
readWriteLock.writeLock().lock();
System.err.println("写:" + getName() + "\t正在write 操作\t" + getMyAccount() + "账户,当前金额为:" + myAccount.getCash());
getMyAccount().setCash(getMyAccount().getCash() + getIoCash());
System.err.println("操作成功:金额为" + getIoCash() + "\t当前金额为:" + getMyAccount().getCash()+"\n\n");
} catch (Exception e) {
e.printStackTrace();
} finally {
/*释放写锁*/
/**
* 一般用lock或者 readwritelock时,需要把
unlock方法放在一个 fianlly 块中,因为程序运行的时候可能会
出现一些我们人为控制不了的因素,导致锁一直没释放,那其他线程就进不来了.
*/
readWriteLock.writeLock().unlock();
}
}
}
}
package dmeo9;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class DemoReadWriteLock {
public static void main(String[] args){
MyAccount myAccount = new MyAccount("工商银行95599200901215522",160000);
ReadWriteLock readWriteLock = new ReentrantReadWriteLock(false);
ExecutorService executorService = Executors.newFixedThreadPool(2);
User u1 = new User("张三", myAccount, -4000, readWriteLock, false);
User u2 = new User("小明", myAccount, 6000, readWriteLock, false);
User u3 = new User("小明", myAccount, -8000, readWriteLock, false);
User u4 = new User("小明", myAccount, 800, readWriteLock, false);
User u5 = new User("小明他爹", myAccount, 0, readWriteLock, true);
executorService.execute(u1);
executorService.execute(u2);
executorService.execute(u3);
executorService.execute(u4);
executorService.execute(u5);
/*关闭线程池*/
executorService.shutdown();
}
}
输出:
写:张三 正在write 操作 dmeo9.MyAccount@1a8fdcaa账户,当前金额为:160000
操作成功:金额为-4000 当前金额为:156000
写:小明 正在write 操作 dmeo9.MyAccount@1a8fdcaa账户,当前金额为:156000
操作成功:金额为6000 当前金额为:162000
写:小明 正在write 操作 dmeo9.MyAccount@1a8fdcaa账户,当前金额为:162000
操作成功:金额为-8000 当前金额为:154000
写:小明 正在write 操作 dmeo9.MyAccount@1a8fdcaa账户,当前金额为:154000
操作成功:金额为800 当前金额为:154800
读:小明他爹 正在read 查询 dmeo9.MyAccount@1a8fdcaa 账户,当前金额为:154800