在多线程并发编程中Synchronized
一直是元老级角色,很多人都会称呼它为重量级锁,但是随着Java SE1.6
对Synchronized
进行了各种优化之后,有些情况下它并不那么重了。
CAS(Compare and Swap),用于在硬件层面上提供原子性操作。
基础
Java中的每一个对象都可以作为锁。
- 对于同步方法,锁是当前实例对象。
- 对于静态同步方法,锁是当前对象的Class对象。
- 对于同步方法块,锁是
Synchonized
括号里配置的对象。
当一个线程试图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁。那么锁存在哪里呢?锁里面会存储什么信息呢?
线程对锁的竞争
当多个线程同时请求某个对象监视器时,对象监视器会设置几种状态用来区分请求的线程:
Contention List
:所有请求锁的线程将被首先放置到该竞争队列Entry List
:Contention List中那些有资格成为候选人的线程被移到Entry ListWait Set
:那些调用wait方法被阻塞的线程被放置到Wait SetOnDeck
:任何时刻最多只能有一个线程正在竞争锁,该线程称为OnDeckOwner
:获得锁的线程称为Owner!Owner
:释放锁的线程
新请求锁的线程将首先被加入到ConetentionList
中,当某个拥有锁的线程(Owner状态)调用unlock之后,如果发现EntryList
为空则从ContentionList
中移动线程到EntryList