锁
锁
java5开始,java提供了锁对象,主要是在多线程的情况下对资源的封锁,保证多线程下资源的正确性,主要有三个接口。
- Condition
- 将Object监视器方法拆分为截然不同的对象,将这些对象与任意Lock实现组合使用,为每个对象提供多个等待set
- Lock
- 实现了比Sychronized关键字更加广泛的锁定操作。
- ReadWriteLock
- 维护了一对相关的锁定,一个用于写,一个用于读。
public class LockTest1 {
public static void main(String[] args) {
// 创建一个账户
Account ac = new Account("123546789",10000);
// 创建一个锁对象
Lock lock = new ReentrantLock();
// 创建一个线程池
ExecutorService es = Executors.newFixedThreadPool(10);
// 模拟多用户并发操作一个账户
User u1 = new User("他大舅", ac, 1000, lock);
User u2 = new User("他二舅", ac, -500, lock);
User u3 = new User("他三舅", ac, 2000, lock);
User u4 = new User("他大姨", ac, -3800, lock);
es.submit(u1);
es.submit(u2);
es.submit(u3);
es.submit(u4);
es.shutdown();
}
}
class User implements Runnable{
private String name;
private Account ac;
private int money;
private Lock lock;
public User(String name,Account ac,int money,Lock lock){
this.name = name;
this.ac= ac;
this.money = money;
this.lock = lock;
}
public void run() {
String str;
if (money>0) {
str = "存入";
}else {
str = "取出";
}
lock.lock();
System.out.println(name+"操作账户 ->"+ac.getAid());
ac.setBalance(ac.getBalance()+money);
System.out.println("操作 -> "+str+",操作金额 ->"+money+"账户余额 -> "+ac.getBalance());
lock.unlock();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Account getAc() {
return ac;
}
public void setAc(Account ac) {
this.ac = ac;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
public Lock getLock() {
return lock;
}
public void setLock(Lock lock) {
this.lock = lock;
}
}
class Account{
private String aid;
private int balance;
public Account(String aid, int balance) {
this.aid = aid;
this.balance = balance;
}
public String getAid() {
return aid;
}
public void setAid(String aid) {
this.aid = aid;
}
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
@Override
public String toString() {
return "Account [aid=" + aid + ", balance=" + balance + "]";
}
}
// 输出
他二舅操作账户 ->123546789
操作 -> 取出,操作金额 ->-500账户余额 -> 9500
他大舅操作账户 ->123546789
操作 -> 存入,操作金额 ->1000账户余额 -> 10500
他大姨操作账户 ->123546789
操作 -> 取出,操作金额 ->-3800账户余额 -> 6700
他三舅操作账户 ->123546789
操作 -> 存入,操作金额 ->2000账户余额 -> 8700
- 上面使用可以优雅的解决并发情况下资源的安全访问,但并不能读写分离,称哪一类锁为普通的锁。为了提高性能,java提供了读写锁,在读的地方使用读锁,再写的地方使用写锁,灵活控制,在一定程度上提高程序的执行效率。
- 实例同普通锁基本相同