美文网首页
Java synchronized关键字和monitor

Java synchronized关键字和monitor

作者: Leocat | 来源:发表于2017-01-11 11:39 被阅读170次

最近在看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;
    }
}

相关文章

网友评论

      本文标题:Java synchronized关键字和monitor

      本文链接:https://www.haomeiwen.com/subject/cwxrbttx.html