多线程: 锁对象和条件对象

锁对象

用ReentrantLock保护代码块基本结构:

public class Bank {
	private Lock bankLock = new ReentrantLock();
	...
	public void transfer(int from, int to, int amount) {
		bankLock.lock();
		try {
			...
		} finally {
			bankLock.unlock();  //确保临界区代码抛出异常,锁必须被释放
		}
	} 
}

每个Bank对象都有自己的ReentrantLock对象。访问不同的Bank对象,会得到不同的锁对象。

锁是可重入的,获得锁的线程可以重复获得相同的锁,调用其他使用相同锁的方法,锁用一个持有计数来跟踪对lock方法的嵌套调用。

条件对象

线程进入临界区,发现需要某条件满足后才能执行。需要使用一个条件对象来管理获得锁但无法执行的线程。

一个锁对象可以有一个或多个相关的条件对象,使用newCondition方法获得一个条件对象。
condition.await(); 线程阻塞,放弃锁,进入该条件的等待集
condition.signalAll(); 唤醒所有等待该条件的线程,解除阻塞状态,线程试图重新获得锁

class Bank
{
	private final double[] accounts;
	private Lock bankLock;
	private Condition sufficientFunds;
    
    public Bank() {
        ...
		bankLock = new ReentrantLock();
		sufficientFunds = bankLock.newCondition();
	}
	
	public void transfer(int from, int to, int amount) throws InterruptedException{
		bankLock.lock();
		try {
			while (accounts[from] < amount)
				sufficientFunds.await();  //账户钱不够线程阻塞
			//transfer
			sufficientFunds.signalAll();
		} finally {
			bankLock.unlock();
		}
	}
}

猜你喜欢

转载自blog.csdn.net/baidu_25104885/article/details/88045106