Lock
和Condition
接口为程序设计人员提供了高度的锁定控制。然而,大多数情况下,并不需要那样的控制,并且可以使用一种嵌入到Java语言内部的机制。从1.0版开始,Java中的每一个对象都有一个内部锁。如果一个方法用synchronized
关键字声明,那么对象的锁将保护整个方法。也就是说,要调用该方法,线程必须获得内部的对象锁。- 内部对象锁只有一个相关条件。wait方法添加一个线程到等待集中,
notifyAll
/notify
方法解除等待线程的阻塞状态。等价于intrinsicCondition.await()
intrinsicConditionsigalAll()
wait
,notifyAll
以及notify
方法时Object
类的final
方法。- 使用synchronized关键字,来管理模拟银行转账中的多线程同步。
public class Bank {
public synchronized void transfer(int from,int to,double amount) throws InterruptedException{
while (accounts[from] < amount){
wait();
}
System.out.print(Thread.currentThread());
accounts[from] -= amount;
System.out.printf("%10.2f from %d to %d", amount, from, to);
accounts[to] += amount;
System.out.printf("Total Balance: %10.2%n",getTotalBalance());
notifyAll();
}
private synchronized double getTotalBalance() {
double sum = 0;
for (double a : accounts)
sum = sum + a;
return sum;
}
}
- 将静态方法声明为
synchronized
也是合法的。如果调用这种方法,该方法获得相关的类对象的内部锁。例如,如果Bank
类有一个静态同步的方法,那么当该方法被调用时,Bank.class
对象的锁被锁住。因此,没有其它线程可以调用同一个类的这个或任何其它的同步静态方法。