java5开始,java提供了锁对象,主要是在多线程的情况下对资源的*,保证多线程下资源的正确性,主要有三个接口。

  1. Condition
  • 将Object监视器方法拆分为截然不同的对象,将这些对象与任意Lock实现组合使用,为每个对象提供多个等待set
  1. Lock
  • 实现了比Sychronized关键字更加广泛的锁定操作。
  1. 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提供了读写锁,在读的地方使用读锁,再写的地方使用写锁,灵活控制,在一定程度上提高程序的执行效率。
  • 实例同普通锁基本相同
上一篇:21. java面向对象 - JavaBean


下一篇:手动计算UTXO