线程同步之 Synchronized Statements

线程同步 提供了两种策略

  1. Synchronized Methods

  2. Synchronized Statements

本文介绍 Synchronized Statements

不过,需要先了解一下 Intrinsic Locks

Intrinsic Locks and Synchronization

同步机制的实现,是围绕被称为 intrinsic lock 的内部实例实现的。Intrinsic lock 在同步机制中发挥两个作用:强制独占访问对象状态的权限,并建立可见的 happens-before 关系

每一个对象都有一个 intrinsic lock 与之关联。一般的,一个需要独占某对象的访问权限的线程,在访问该对象的资源之前,需要请求这个对象的 intrinsic lock,并在访问结束后释放该 intrinsic lock 。在获取 lock 到释放 lock 这之间,该线程拥有该 intrinsic lock 。只要一个线程拥有 intrinsic lock,其他线程将不会获取该 lock 。当试图请求一个已经被独占的 lock 时,其他线程将会阻塞 。

当一个线程释放 intrinsic lock,该动作将会与随后的获取 lock 的请求之间,建立一个 happens-before 关系 —— 即随后的被阻塞的线程,可以得知 lock 已被释放。

Synchronized Methods 中的 Locks

当一个线程调用一个对象的 synchronized method,该线程将自动获取这个对象的 intrinsic lock,然后在方法 return 时释放 lock 。即使 method 是因为没有 catch 的 exception 而返回, 也会释放 lock

BTW: 当调用一个 static synchronized method 时(即该方法与一个类关联,而不是一个对象),会发生什么?线程会向该类的 Class 对象请求 intrinsic lock。

Synchronized Statements

实现线程同步的另一种方法,就是使用 Synchronized Statements。

与 Synchronized Methods 不同,Synchronized Statements 不能自动获取对象的 intrinsic lock,而是必须明确指明提供了 intrinsic lock 的对象(这也是 Synchronized Statements 的优点,稍后会提到)

例子:

public void addName(String name) {
    synchronized(this) {
        lastName = name;
        nameCount++;
    }
    nameList.add(name);
}

上边的例子中,不同线程调用 addName 方法在修改 lastName 和 nameCount 时,将会同步。在调用 nameList.add 方法时将不会进行同步。


再说一个例子。假定类 MyLunch 有两个字段 c1 和 c2,且这两个字段绝不会用在一起。所有对 c1 和 c2 的修改都必须分别同步,但没必要再修改 c1 时避免对 c2 的修改,反而使得程序效率不高。

因此,不使用 Synchronized Methods 或 synchronized (this),而是独立的创建两个对象,提供各自独立的 intrinsic lock

public class MsLunch {
    private long c1 = 0;
    private long c2 = 0;
    private Object lock1 = new Object();
    private Object lock2 = new Object();

    public void inc1() {
        synchronized(lock1) {
            c1++;
        }
    }

    public void inc2() {
        synchronized(lock2) {
            c2++;
        }
    }
}

Reentrant Synchronization

一个线程不能请求到一个已经被其它线程占用的 lock,但一个线程可以请求到一个已经被自己占中的 lock。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值