24.线程的应用
1.等待之后超时
while(结果未返回 && 时间未到)
wait();
2.线程池
要有队列,状态
Worker实现Runnable接口,循环从jobs队列取任务执行,获取不到就wait();
execute(Job job)时,唤醒jobs
3.基于线程池Web服务器
思路:开一个Socket服务,每次accept后,把这个一对一服务放封装成job类,放到jobs队列里
|--LockSupport
工具类,有park、unpark阻塞唤醒线程
|--Condition
相当于Lock中的wait和notify,区别是wait等待队列只能有一个,Condition可以有多个
Condition队列类似于AQS队列
每个Condition下面有一个等待await的等待队列
Lock.newCondition()获取condition
Lock.await(); = wait
Lock.singal();=notify
|--ConcurrentHashMap
问题:HashMap线程不安全导致Entry链表编程环,引发死循环。
HashTable效率低
解决:Segment包含HashEntry数组
Segment是一种可重入锁(ReentrantLock)
实现:segment数量是2的n次方,默认16
每一个segment的容量=每个segment里HashEntry*负载因子
如何放入数据:再散列确保数据分散后放入segment
get方法:不加锁,而是用volatile
1.8更新:没有了segment,横向用Node链表替代,Node被调用取时就synchronize加锁。当没Node底下链表超过8个,将加锁
4.ConcurrentLinkedQueue
非阻塞
入队:定位尾节点,不成功cvs重试(为了减少CVS,控制尾节点更新频率)
出队:
1.等待之后超时
while(结果未返回 && 时间未到)
wait();
2.线程池
要有队列,状态
Worker实现Runnable接口,循环从jobs队列取任务执行,获取不到就wait();
execute(Job job)时,唤醒jobs
3.基于线程池Web服务器
思路:开一个Socket服务,每次accept后,把这个一对一服务放封装成job类,放到jobs队列里
|--LockSupport
工具类,有park、unpark阻塞唤醒线程
|--Condition
相当于Lock中的wait和notify,区别是wait等待队列只能有一个,Condition可以有多个
Condition队列类似于AQS队列
每个Condition下面有一个等待await的等待队列
Lock.newCondition()获取condition
Lock.await(); = wait
Lock.singal();=notify
|--ConcurrentHashMap
问题:HashMap线程不安全导致Entry链表编程环,引发死循环。
HashTable效率低
解决:Segment包含HashEntry数组
Segment是一种可重入锁(ReentrantLock)
实现:segment数量是2的n次方,默认16
每一个segment的容量=每个segment里HashEntry*负载因子
如何放入数据:再散列确保数据分散后放入segment
get方法:不加锁,而是用volatile
1.8更新:没有了segment,横向用Node链表替代,Node被调用取时就synchronize加锁。当没Node底下链表超过8个,将加锁
4.ConcurrentLinkedQueue
非阻塞
入队:定位尾节点,不成功cvs重试(为了减少CVS,控制尾节点更新频率)
出队: