synchronized关键字

概要

synchronized能保证原子性、可见性、有序性。原理如下:

原子性:synchronized编译后产生字节码指令monitorenter、monitorexit,这两个指令最终对应到JVM底层就是原子操作lock、unlock。

可见性:对一个共享变量执行unlock前先把此变量的值从线程的工作内存同步到主内存。

有序性:由于一个共享变量在同一时刻只允许一条线程对其执行lock操作,因此持有同一个锁的两个同步块只能串行进入。

 

原理:(P391)

synchronized编译后在同步块前后分别形成monitorenter、monitorexit字节码指令,这两个指令需要一个Reference类型参数指明要锁定和解锁的对象(没明确指定时根据synchronized修饰的是类方法还是实例方法取相应的Class对象或对象实例作为锁对象)。

  • 执行monitorenter时首先尝试获取对象的锁。若对象没被锁定或当前线程已拥有了该对象的锁,则锁计数加1;相应地,执行monitorexit时锁计数减1,计数为0时释放锁。
  • 若当前线程获取锁对象失败则阻塞等待,直到对象锁被占有该锁的另一个线程释放,并且当前线程抢到该锁。

synchronized同步块对同一个线程来说是可重入的,不会出现把自己锁死的问题。

 

下面详述

synchronized用来修饰代码块或方法,其作用是让访问该方法或代码块的线程获取方法所属对象的同步锁,以实现同步操作。

1、

在java中,每一个对象有且仅有一个同步锁。这也意味着,同步锁是依赖于对象而存在;我们通过调用某对象的synchronized方来获取该对象的同步锁。
我们将synchronized的基本规则总结为下面3条,并通过实例对它们进行说明。

  • 第一条: 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程对“该对象”的该“synchronized方法”或者“synchronized代码块”的访问将被阻塞。
  • 第二条: 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程仍然可以访问“该对象”的非同步代码块。
  • 第三条: 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程对“该对象”的其他的“synchronized方法”或者“synchronized代码块”的访问将被阻塞。

实例锁 -- 锁在某一个实例对象上。如果该类是单例,那么该锁也具有全局锁的概念。实例锁对应的就是synchronized关键字。
全局锁 -- 该锁针对的是类,无论实例多少个对象,那么线程都共享该锁。全局锁对应的就是static synchronized(或者是锁在该类的class或者classloader对象上)。

关于“实例锁”和“全局锁”有一个很形象的例子:

pulbic class Something {
  public synchronized void isSyncA(){}
  public synchronized void isSyncB(){}
  public static synchronized void cSyncA(){}
  public static synchronized void cSyncB(){}
}
假设,Something有两个实例x和y。分析下面4组表达式获取的锁的情况。
(01) x.isSyncA()与x.isSyncB() //不能同时访问
(02) x.isSyncA()与y.isSyncA() //可以同时访问
(03) x.cSyncA()与y.cSyncB() //不能同时访问
(04) x.isSyncA()与Something.cSyncA() //可以同时访问

每个对象都有一个锁和一个等待队列,类对象也不例外。 synchronized保护的是对象:对实例方法,保护的是当前实例对象this;对静态方法,保护的是类对象。

synchronized静态方法和synchronized实例方法保护的是不同的对象,不同的两个线程,可以同时,一个执行synchronized静态方法,另一个执行synchronized实例方法。

任何对象都可以作为锁对象

2、

synchronized是可重入的且保证内存可见性:在释放锁时,所有写入都会写回内存,而获得锁后,都会从内存中读最新数据。

 

参考资料:

1、《深入理解Java虚拟机——JVM高级特性与最佳实践》

2、更多详见 synchronized实现原理

 

posted @ 2017-03-04 18:50  March On  阅读(319)  评论(0编辑  收藏  举报
top last
Welcome user from
(since 2020.6.1)