Java中每一个对象都有一个内部锁。若方法用synchronized关键字声明,对象的锁将保护整个方法。调用同步方法,线程需要获得内部的对象锁。
public synchronized void method() {
...
}
等价于
public void method() {
this.intrinsicLock.lock(); //对象内部锁
try {
...
} finally {
this.intrinsicLock.unlock();
}
}
对象内部锁只有一个相关条件。
wait()添加线程到等待集中,notifyAll()/notify()解除等待线程的阻塞状态
等价于intrinsicCondition.await()和intrinsicCondition.signalAll()
public class Bank {
private double[] accounts;
public synchronized void transfer(int from, int to, int amount) throws InterruptedException{
while (accounts[from] < amount)
wait();
//transfer
notifyAll();
}
}
静态同步方法
静态同步方法获得相关的类对象的内部锁。
eg. Bank类的静态同步方法被调用是,Bank.class对象的锁被锁住,其他线程不能调用同一个类的这个或其他的静态同步方法。
内部锁的局限性
- 不能中断正在试图获得的线程
- 试图获得锁时不能设定超时
- 每个锁只有单一条件,可能不够
同步代码块(同步阻塞)
synchronized (obj) {
...
}
需要获得obj锁才能执行该代码块
eg.需要对list做同步处理,可以写成synchronized(list)
synchronized(this)代码块和synchronized方法一样需要获得对象内部锁才能执行。
synchronized(非this对象)代码块和synchronized方法异步执行。
静态同步方法与synchronized(Bank.class)相当。