线程间同步的机制
来源:互联网 发布:淘宝心等级查询 编辑:程序博客网 时间:2024/05/17 14:16
一家之言,仅供擦考。
希望能在J.U.C系列的文章,尽最大的可能将Java的多线程同步的知识用较为轻松的语言描述清晰。
在正式开始J.U.C之前,我想先把一些理论知识描述清楚,毕竟不管是哪门高级语言,理论基础都是不能避开的.
同步和异步
我们在很多场合都会听到这个词,目前java语言的发展,大量的第三库Framework采用异步任务的方式来架构自己的模型。
这个概念在多线程编程中出现的非常频繁,下面来说说我对这两个概念的理解:
1.从OS的发展来看,最早期的单任务OS(硬件环境:单CPU单计算单元),不存在多线程,假设N个Task需要完成,那么OS需要串行化执行这N个任务,这里个N个Task利用CPU一个一个的顺序执行(这里我们可以用同步或者异步去描述这N个任务么?可以说成是这N个任务同步的执行吗?)。
2.随着OS的发展,出现了多任务(多道处理)操作系统,这个技术彻底改变了计算机的运行方式,运行的OS之上的Task不在是 task1 - > task2 - >..... - >taskn串行计算模式,而是利用OS对CPU的调度算法(最常见的CPU时间分片)来并行执行这N个Task的执行(即使依旧是单CPU单计算单元,在人类的感知体系下好像是并行一样)。OS提出了了一个重要的概念就是线程。
什么是线程(Thread)?
a.OS调度CPU的最小单位;
b.OS不能独立为其分配RAM,必须依赖其所属的Process(进程);
c.Task运行的容器。
自从有了线程的概念之后,随之而来的就是异步的概念:多个线程各自独立的运行各自的Task,互相不收影响。所以这个N个任务的执行就被说成了异步执行(隐藏条件:这N个Task各自占用一个线程)。再然后就成了这N个线程异步的执行这N个Task。后面再演变就有了Task1是异步执行的这样的说法。
3.随着运行在OS上的应用发展,这N个Task之间产生了一些微妙的变化,Task1假设是启动音频程序,Task2是某个音乐App。那么就存在Task1必须首先执行完毕,然后Task2才能运行。Task1和Task2分别运行在自己的容器中(Thread A和Thread B),这时有趣的事情发生了,OS在调度CPU的时候要保证Thread A必须完全执行完毕才执行Thread B。然后Thread A和Thread B产生的这种关系被称为同步关系。
在2和3中,我们看到同步和异步说的是线程间的一种关系,而产生线程这种关系的原因是由于Task之间的关系来决定的:Task之间没有关系,则运行Task的线程是异步关系;Task之间存在先后顺序关系,则运行Task的线程是同步关系。现在我们回头来看1中的问题,Task之间不存在关系,它们则应该是异步关系,但是,他们运行的环境可以看成是一个单线程环境,他们的执行有明显的顺序关系,他们则是同步关系。有点晕了,那到底1中的Task之间是什么关系,其实很简单,他们确实没有关系,让Task之间产生关系的实际上是那时计算机的运行模式,所以不用去管怎么称呼它,而且Task之间的关系严格上来说,不应该用同步和异步来描述。
是时候进行一波总结了:
在严谨的知识体系下,我们是在描述下面的概念:
线程间同步:描述OS在调度Thread在CPU的使用权的问题上存在顺序关系。(多线程环境下,线程间的等待唤醒机制)
线程间异步:描述OS在调度Thread在CPU的使用权的问题上没有顺序关系。
在描述业务的时候,我们经常指下面的概念(比如HTTP请求响应式的业务网络模型,Http Server先读后写,存在同步关系):
任务间同步:描述两个Task存在某种顺序关系。
任务间异步:描述两个Task没有顺序关系。
线程间同步和临界资源的互斥访问
if(S<0){
将当前线程置入
S的等待队列中,
当前线程阻塞
}else{
继续运行
}S = S+1;
if(s <=0 ){
将S的等待队列中的线程
取出来一个,并将其置为 就绪状态
}else{
继续运行
}busy等待flag : if(s > 0){
s = s -1;
}else{
loop(s > 0){
goto flag:
}
}s = s + 1;
OS提供的线程同步方案
一.Mutex互斥量
share int various;
share boolean mutex; //mutex标识(本质上是二元信号量)
function add(count){
<span style="white-space:pre"></span>P(mutex); //lock
<span style="white-space:pre"></span>various = various + <span style="font-family: Arial, Helvetica, sans-serif;">count</span>;
<span style="white-space:pre"></span><span style="font-size:14px;">V</span>(mutex);<span style="white-space:pre"></span> //unLock
}
递归Mutex和非递归Mutex(可重入锁[Reentrant]和非可重入锁)
二.Condition条件变量
share Array queue; //临界资源
share bool isFullCondition = flase; //二元信号量
share bool isEmptyCondition = true; //二元信号量
share int size = 0;share object mutex; //mutex(非递归)
function put(Object obj){
<span style="white-space:pre"></span>P(mutex);
<span style="white-space:pre"></span>while(isFullCondition){
<span style="white-space:pre"></span>P(<span style="font-family: Arial, Helvetica, sans-serif;">isFullCondition</span><span style="font-family: Arial, Helvetica, sans-serif;">);</span><span style="white-space:pre"></span>}
<span style="white-space:pre"></span>queue.put(obj);
<span style="white-space:pre"></span>size = size + 1;
<span style="white-space:pre"></span>if(size == 10){
<span style="white-space:pre"></span>isFullCondition = true;
<span style="white-space:pre"></span>V(<span style="font-family: Arial, Helvetica, sans-serif;">isEmptyCondition</span><span style="font-family: Arial, Helvetica, sans-serif;">);</span>
<span style="white-space:pre"></span>}
<span style="white-space:pre"></span>V(mutex);
<span style="font-family: Arial, Helvetica, sans-serif;"><span style="white-space:pre"></span>}</span>
function get(){
P(mutex);
while(isEmptyCondition){
P(<span style="font-family: Arial, Helvetica, sans-serif;">isEmptyCondition</span><span style="font-family: Arial, Helvetica, sans-serif;">);</span>
}
queue.get();
<span style="white-space:pre"></span>size = size - 1;
<span style="white-space:pre"></span>if(size == 0){
<span style="white-space:pre"></span>isEmptyCondition = true;
<span style="white-space:pre"></span><span style="font-family: Arial, Helvetica, sans-serif;">V(</span><span style="font-family: Arial, Helvetica, sans-serif;">isFullCondition</span><span style="font-family: Arial, Helvetica, sans-serif;">);</span>
<span style="white-space:pre"></span>}
<span style="white-space:pre"></span>V(mutex);
}
三.Semaphore信号量
- 线程间同步的机制
- 线程的同步机制
- 线程的同步机制
- 线程的同步机制
- 线程间的同步机制(1)
- 线程间的同步机制(2)
- 线程间同步机制的总结
- 进程线程间的同步机制
- linux的线程同步机制
- linux的线程同步机制
- linux的线程同步机制
- Linux的线程同步机制
- linux的线程同步机制
- linux的线程同步机制
- linux的线程同步机制
- 线程的同步机制分析
- 进程/线程间同步机制。
- 线程间同步机制----互斥锁
- Android UI学习笔记------布局
- get chinese label from app
- day(4) 动作
- 20.JavaWeb基础 Struts 1 多人开发
- 安装Oracle11快捷版,Oracle-12560
- 线程间同步的机制
- Devpress-XtraGrid-GridControl笔记
- 利用PHP SOAP实现WEB SERVICE
- 屌丝如何成功逆袭?
- CSS 中文字体对应英文和Unicode编码
- php做推送服务端实现android消息推送
- 带你了解BOM
- 小心指针被delete两次 情况如下试例 ! ———【Badboy】
- 2014年8月编程语言排行