资讯专栏INFORMATION COLUMN

线程同步之 Synchronized Statements

Vultr / 2104人阅读

摘要:线程同步提供了两种策略本文介绍不过,需要先了解一下同步机制的实现,是围绕被称为的内部实例实现的。在获取到释放这之间,该线程拥有该。当试图请求一个已经被独占的时,其他线程将会阻塞。实现线程同步的另一种方法,就是使用。

线程同步 提供了两种策略

Synchronized Methods

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。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/65288.html

相关文章

  • 线程同步 Synchronized Methods

    摘要:这保证了该对象的所有状态的改变,对于所有线程是可见的为构造函数添加是语法错误。 Synchronized Methods 线程同步 提供了两种策略 Synchronized Methods Synchronized Statements 本文介绍 Synchronized Methods 一个例子 使用 synchronized 关键字,使一个方法为 synchronized pu...

    sourcenode 评论0 收藏0
  • JVM解剖公园

    摘要:为此,引入转换查找缓冲缓存最近的转换记录。这个优化技术,可以看到将原本对对象的字段访问,替换为一个局部变量的访问。当所有线程都在已知的位置停止的时候,被认为是到达了安全点。检查安全点请求的代码 showImg(https://segmentfault.com/img/bVbwfcz?w=1024&h=576); 1、JVM锁粗化和循环原文标题:JVM Anatomy Quark #1:...

    imingyu 评论0 收藏0
  • 死磕 java同步系列synchronized解析

    摘要:问题的特性的实现原理是否可重入是否是公平锁的优化的五种使用方式简介关键字是里面最基本的同步手段,它经过编译之后,会在同步块的前后分别生成和字节码指令,这两个字节码指令都需要一个引用类型的参数来指明要锁定和解锁的对象。问题 (1)synchronized的特性? (2)synchronized的实现原理? (3)synchronized是否可重入? (4)synchronized是否是公平锁?...

    番茄西红柿 评论0 收藏0
  • 死磕 java同步系列synchronized解析

    摘要:问题的特性的实现原理是否可重入是否是公平锁的优化的五种使用方式简介关键字是里面最基本的同步手段,它经过编译之后,会在同步块的前后分别生成和字节码指令,这两个字节码指令都需要一个引用类型的参数来指明要锁定和解锁的对象。问题 (1)synchronized的特性? (2)synchronized的实现原理? (3)synchronized是否可重入? (4)synchronized是否是公平锁?...

    番茄西红柿 评论0 收藏0
  • 死磕 java同步系列synchronized解析

    摘要:问题的特性的实现原理是否可重入是否是公平锁的优化的五种使用方式简介关键字是里面最基本的同步手段,它经过编译之后,会在同步块的前后分别生成和字节码指令,这两个字节码指令都需要一个引用类型的参数来指明要锁定和解锁的对象。问题 (1)synchronized的特性? (2)synchronized的实现原理? (3)synchronized是否可重入? (4)synchronized是否是公平锁?...

    luxixing 评论0 收藏0

发表评论

0条评论

Vultr

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<