最近在看Java并发相关的东西,然后再看文档的时候经常看到monitor
这个词,例如Object.wait的文档里有这么一句:
The current thread must own this object's monitor.
因为不清楚这个词是什么意思,所以特地查了一下,记录一下。
当我们在写同步相关的代码,经常会使用到synchronized这个关键字,synchronized方法或者synchronized代码块,例如
public class Account {
private int balance;
// synchronized方法
synchronized public int getBalance() {
return balance;
}
public void setBalance(int balance) {
// synchronized代码块
synchronized (this) {
this.balance = balance;
}
}
}
之所以这个synchronized关键字会起带同步的作用,就是因为monitor。monitor只是一个简称,通常称为intrinsic lock
或者monitor lock
。
每个对象都有一个monitor lock
与之相关联,如果一个线程需要排他和一致访问对象的某个域,它就必须先获得对象的monitor lock
,当它完成任务之后再释放这个锁,让其它线程可以访问到。只要一个线程获得了一个monitor lock
,那么其它线程就没办法获取到这个锁。也就是说,当其它线程尝试获得锁的时候就会阻塞。
对了,当synchronized的是静态方法,那么获取的monitor lock
应该是这个类对应的Class
对象的锁,如下所示。在静态方法中,synchronized代码块如果如果想要获取this
的锁就会报错,因为静态方法是属于类的,不是属于对象。但是我们可以通过获取Account.class
对象的锁来做互斥操作。
class Account {
private static int defaultBalance = 5;
synchronized public static int getDefaultBalance() {
return defaultBalance;
}
public static void setDefaultBalance(int balance) {
synchronized (Account.class) {
defaultBalance = balance;
}
}
}
synchronized方法获取的是当前对象的锁,而对于synchronized代码块,可以使用通过获取其它对象的锁来做同步,如下代码中,setBalance
方法里,就是通过获取lock对象的锁来做互斥操作。
class Account {
private int balance;
private final Object lock = new Object();
public void setBalance(int balance) {
// 获取lock对象的锁
synchronized (lock) {
this.balance = balance;
}
}
synchronized public int getBalance() {
return balance;
}
}