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提供了读写锁,在读的地方使用读锁,再写的地方使用写锁,灵活控制,在一定程度上提高程序的执行效率。
  • 实例同普通锁基本相同
posted @ 2019-10-21 09:47  kungFuPander  阅读(124)  评论(0编辑  收藏  举报