1. LockSupport类
AQS架构使用LockSupport来实现线程的休眠,时间性休眠,唤醒…
2. AQS架构-所有同步器的基本架构
—– a. 基于AQS架构的同步器基本上只需要实现四个函数
1. tryAcqurie(int) — 线程会调用这个函数来做能否互斥的获取同步器资源的尝试的逻辑
2. tryRelease(int) — 线程会调用这个函数来做能否互斥的释放同步器资源的尝试的逻辑
3. tryAcqurieShared(int) — 线程会调用这个函数来做能否共享的获取同步器资源的尝试的逻辑
4. tryReleaseShared(int) — 线程会调用这个函数来做能否共享的释放同步器资源的尝试的逻辑
—– b. 基于AQS架构同步器分为
互斥同步器 例如ReentrantLock
共享同步器 例如Semaphore
互斥和共享共存的同步器ReentrantReadWriteLock
接下来会有文章依次介绍这些同步器的实现
—– c. AQS数据结构
1. 对于首次进入时获取资源失败的Thread,会将其封装到一个NODE数据块里面
2. 会维护两个NODE引用,分别指向NODE双向链表的头和尾,这样来实现FIFO
3. 对于同步器所拥有的资源就是使用一个INT来表示,这也就是互斥和共享共存的
同步器同时共享的线程只能是2个BYTE能表示的长度的原因,所有又推出了一个LONG型的AQS架构
—– d. AQS核心代码
1. acquireQueued() 实现了线程不可中断模式下的互斥获取资源
其主要逻辑是一个死循环
a. 线程所属的NODE->prev是HEAD才会调用tryAcqurie执行尝试获取锁的逻辑
b. 如果尝试获取锁成功则head=NODE,以及一个释放HARD REFERENCE的操作
c. 返回线程在WAIT期间是否被标记中断 —> 线程摆脱同步器的控制
d. 对tryAcqurie尝试失败后是否需要WAIT做出判断 —- 重点处
1. 如果前一个NODE处于WAIT则它一定要WAIT
2. 如果前一个NODE处于CANCEL则做一个链表的删除工作
3. 如果前一个NODE是最后加入的则将其标记为WAIT
4. 2和3会让线程再做一次尝试,不会阻塞线程
e. 如果线程需要阻塞则调用LockSupport.park阻塞,两种方式会让线程醒来
1. 线程被标记中断
2. 别的线程用LockSupport.unpark了它,有线程释放了互斥资源
f. 线程醒来循环到a
g. 程序的逻辑就是一个尝试获取资源,线程阻塞,被唤醒的轮回
2. doAcquireInterruptibly()实现了线程可中断模式下的互斥获取资源
其原理和acquireQueued()一样,不同之处是线程在被中断后即在1.e.1条件下会直接退出死循环
3. doAcquireNanos()实现了线程可中断+记时模式下的互斥获取资源
a. 在阻塞前会先计算阻塞的时间,进入休眠
b. 如果被中断则会判断时间是否到了
1. 如果没到则且被其他线程设置了中断标志,退出那个轮回,抛出中断异常,如果没有被设置中断标记则是前一个线程
释放了资源再唤醒了它,其继续走那个轮回,轮回中,如果tryAcquire成功则摆脱了同步器的控制,否则回到a
2. 如果时间到了则退出轮回,获取资源失败
4. release()实现了互斥资源的释放,最主要的工作就是将其下一个线程唤醒1.e.2
5. doAcquireShared()实现了线程不可中断模式下的共享获取资源
a. 线程所属的NODE->prev是HEAD才会调用tryAcquireShared执行尝试获取锁的逻辑
b. 如果尝试获取锁成功则head=NODE,以及一个释放HARD REFERENCE的操作
此处和互斥的明显区别是,线程在获取成功后如果还有剩余的资源会唤醒其后的线程
也就是如果其下一个线程也是共享的获取资源,其被唤醒的理由多了个
c. 线程在WAIT期间是否被标记中断则标记,因为这期间的标记状态会被清掉 —> 线程摆脱同步器的控制
d. 对tryAcquireShared尝试失败后是否需要WAIT做出判断 —- 重点处
1. 如果前一个NODE处于WAIT则它一定要WAIT
2. 如果前一个NODE处于CANCEL则做一个链表的删除工作
3. 如果前一个NODE是最后加入的则将其标记为WAIT
4. 2和3会让线程再做一次尝试,不会阻塞线程
e. 如果线程需要阻塞则调用LockSupport.park阻塞,三种方式会让线程醒来
1. 线程被标记中断
2. 别的线程释放了资源LockSupport.unpark了它
3. 其前一个共享线程醒了以后获取了资源而其还有资源也会唤醒它
f. 线程醒来循环到a
g. 程序的逻辑就是一个尝试获取资源,线程阻塞,被唤醒的轮回
6. doAcquireSharedInterruptibly()实现了线程可中断模式下的共享获取资源
其原理和doAcquireShared()一样,不同之处是线程在被中断后即在5.e.1条件下会直接退出死循环
7. doAcquireSharedNanos()实现了线程可中断+记时模式下的共享获取资源
a. 在阻塞前会先计算阻塞的时间,进入休眠
b. 如果被中断则会判断时间是否到了
1. 如果没到则且被其他线程设置了中断标志,退出那个轮回,抛出中断异常,如果没有被设置中断标记则是前一个线程
释放了资源再唤醒了它,其继续走那个轮回,轮回中,如果tryAcquire成功则摆脱了同步器的控制,否则回到a
2. 如果时间到了则退出轮回,获取资源失败
8. releaseShared()和release()一样
—————————————–
[来源:http://www.cnblogs.com/mandela/archive/2011/04/08/2009808.html]
分类目录
- arch/management (17)
- computer (38)
- java/j2ee (304)
- lnmpa (237)
- mac/iphone/ipad/android (11)
- mysql/oracle/postgresql (126)
- os/software (74)
- other (518)
- python (6)
- redis/memcached/mongo (31)
- sitebuild (143)
随便看看
标签云
程序员 创业 人生箴言 eclipse 快捷键 术语 索引 unix命令 vim wordpress java学习笔记 环境变量 oracle内置函数 index 人生 数据类型 nohup tuxedo mysql学习笔记 MS-DOS命令 servlet spring 职场进阶 职业进阶 服务器选购 服务器选型 apache JPA MongoDB 注解 tomcat 子女教育 jquery maven JVM aix命令 网络营销 java异常 seo 人生规划 关键字 css 网络推广 struts 系统优化 成长 frame iframe bluehost jdbc select 我的信仰 oracle函数 cookie HashMap 站长工具 乱码 ArrayList secureCRT jsp session tail find halt 事务 oracle单记录函数 算法 URL window table javascript操作表单元素 String 字符串处理 健康 http 域名 情感 more google A记录 域名解析 netstat 弹出对话框 弹出窗口 框架集 框架 excel 字符串 javascript函数 showModalDialog nginx number 数组 sql frameset 开源程序 java数组 软件 oracle服务友情链接
收藏链接