标签:竞争 作业 追踪 dir 另一个 端口 strong 独立 区别
学习资料来自http://ifeve.com/java-concurrency-thread-directory/
一、多线程
多线程在同一个程序内部并发执行,因此会对相同的内存空间进行并发读写操作。
思考:
二、多线程的优点
1、资源利用率更好
比如CPU在等待磁盘读取的时间非常空闲,可以利用这一段时间去做一些其他的事情。
2、程序设计在某些情况下更简单
比如单线程去操作两个文件的读取和处理,需要记录每个文件的读取和处理状态。相反,如果用两个线程分别处理一个文件,一个线程在读取的时候就会阻塞另一个线程,此时,被阻塞的线程就可以去执行处理的操作。不但提升磁盘和CPU利用率,编程也更加容易实现。
3、程序响应更快
例如服务器在某一个端口监听进来的请求,当一个请求到来时它去处理这个请求,处理完了再返回去监听其他请求。假设这个请求需要占用大量的时间呢?
另一种方式是服务器监听线程把进来的请求传递给工作者线程,然后马上返回去监听,这样就能够接受和处理更多客户端发送过来的请求,服务的响应也更快了。
三、多线程的代价
1、设计更复杂
一般来说,多线程应用程序比单线程应用程序更加复杂,在多线程访问共享数据的时候,线程之间的交互往往非常复杂,不正确的线程同步产生的错误非常难以被发现,并且重现以修复。
2、上下文切换的开销
当CPU执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地数据、程序指针等,然后载入另一个线程的本地数据、程序指针等,最后才开始执行。这种切换叫做上下文切换(context switch),CPU会在一个上下文(context)中执行一个线程,然后切换到另一个上下文(context)执行另外一个线程。
如果没有必要应该尽量减少上下文的切换。
3、增加资源消耗
除了CPU,线程还需要一些内存来维持它本地的堆栈,也需要占用操作系统中一些资源来管理线程。我们可以写一个程序创建100个线程,然后这些线程只是等待什么都不做,然后看看占用了多少内存。
四、并发编程模型
并发编程模型指定了系统中的多线程如何通过协作来完成分配给它们的作业,不同的并发模型采用不同的方式拆分作业,同时线程间的协作和交互方式也不相同。
1、 并发模型与分布式系统之间的相似性
并发模理类似于分布式系统中使用的很多体系结构,在分布式系统中进程之间可以
通信(进程可能在不同的机器中),在并发系统中线程之间也可以相互通信。例如为工作者们(线程)分配作业的模型一般与分布式系统中的负载均衡系统比较相似。
2、 并行工作者
委托者将传入的作业被分配给不同的工作者上,每个工作者完成整个任务,工作者们运作在不同的线程上,甚至可能在不同的CPU上。
优点:容易理解,只需要添加更多的工作者来提高系统的并行度。
缺点:
等待访问共享数据时,线程之间的互相等待会丢失部分并行性,许多并发数据结构是阻塞的,意味着在某个时刻只有一个或者很少的线程能访问,导致共享数据出现竞争状态,出现一定串行化。
3、 流水线模型
也叫反应器系统、事件驱动系统或者无共享模型。
类似于工厂生产线上的工人们,每个工作者只负责作业中的部分工作,当完成了自己这部分工作就转发给下一个工作者,每个工作者在自己的线程中运行,并不会和其他工作者共享状态。
在实际中可能会有多个不同的虚拟流水线同时动作,现实可能是这样的情况。
Actors和Channels
Actors模型中每个工作者都被称为actor。Actor之间可以直接异步地发送和处理消息,actor可以用来实现一个或多个前面描述的那种作业处理流水线。
Channel模型中,工作都之间不直接进行通信。相返,它们在不同的通道中发布自己的消息(事件)。其他工作者可以在这些通道上监听消息,发送者无需知道谁在监听。
流水线模型的优点:
流水线模型的缺点:
4、 函数式执行(Functional Parallelism)
函数式并行的基本思想是采用函数调用实现程序,函数被看作是代理人(agents)或者actor, 函数之间可以像流水线模型(AKA反应器或者事件驱动系统)那样互相发送消息。
思考:使用哪种并发模型好呢?
通常情况下,这个答案取决于你的系统打算做什么。如果你的作业本身就是并行的、独立的并且没有必要共享状态,你可能会使用并行工作者模型去实现你的系统。
很多作业都不是自然并行和独立的,对于这种类型的系统,使用流水线并发模型能够更好的发挥它的优势,而且比并行工作者模型更有优势。
标签:竞争 作业 追踪 dir 另一个 端口 strong 独立 区别
原文地址:http://www.cnblogs.com/tester808/p/6741308.html