首页 > 代码库 > 初识并发

初识并发

为什么有并发?

编程中的相当大一部分都可以通过使用顺序编程来解决。然而,对于某些问题,如果能够并行地执行程序中的多个部分,则会变得非常方便甚至非常必要。并行编程可以使程序执行速度得到极大提高,或者为设计某些类型的程序提供更易用的模型,或者两者皆有。

例如,Web系统是最常见的Java应用系统之一,而基本的Web类库,Servlet具有天生的多线程性,它能使多个用户在同一时间访问Web服务;图形化用户界面也是类似的情况,考虑这样一个程序,它因为将执行某些长期运行的操作,所以最终用户输入会被忽略,从而成为不可响应的程序。

为什么并发速度更快?

当前,Moore定律已经有些过时了(摩尔定律正式失效,半导体行业何去何从?),速度提高是以多核处理器的形式而不是更快的芯片的形式出现的。如果你有一台多处理器的机器,那么就可以在这些处理器之间分布多个任务,从而可以极大地提高吞吐量。

但是,并发通常是提高运行在单处理器上的程序的性能,这听起来有些违背直觉,因为单处理器上运行的并发程序比顺序执行程序增加了所谓的“上下文切换”的代价,使这个问题变得有些不同的是阻塞,如果程序中的某个任务因为该程序控制范围之外的某些条件(通常是IO)而导致不能继续执行,那么我们就说这个任务或线程阻塞了。如果没有并发,则整个程序都将停止下来,直至外部条件发生变化。但是,如果使用并发,那么当一个任务阻塞时,程序中的其他任务还可以继续执行,因此这个程序可以保持继续向前执行。

实现并发的方式:进程和线程

实现并发最直接的方式是在操作系统级别使用进程,进程是运行在它自己的地址空间内的自包容的程序,操作系统会将进程互相隔离开,因此他们不会彼此干涉,并且没有彼此通信的需要,因为他们都是完全独立的。

与此相反的是,Java使用的并发系统会共享诸如内存和IO这样的资源,因此编写多线程程序最基本的困难在于协调不同线程驱动的任务之间对这些资源的使用,以使得这些资源不会同时被多个任务访问。

协作式和抢占式

Java的线程机制是抢占式的,这表示调度机制会周期性地中断线程,将上下文切换到另一个线程,从而为每隔线程都提供时间片,使得每个线程都会分配到数量合理的时间去驱动它的任务。在协作式系统中,每个任务都会自动的放弃控制,这要求程序员要有意识地在每个任务中插入某种类型的让步语句。

初识并发