在多处理器之间分布多个任务,从而提高吞吐量,例如web服务器,在为每一个请求分配一个线程的程序中,它可以将大量的用户请求分布到多个CPU上。
在单处理器上运行并发程序开销确实应该比该程序的所有部分都顺序执行的开销大,因为其中增加了所谓的上下文切换的代价(从一个任务到另一个任务)。但是当发生阻塞,即程序中的某个任务因为该程序控制范围之外的某些条件(IO操作)而导致不能继续执行,那么这个任务或线程被阻塞,如果没有并发,整个程序都将停止下来,如果用并发则其他的任务还会继续执行,从性能的角度看,如果没有任务会阻塞,那么在单处理器上使用并发就没有任何意义。
单处理器 单任务(单线程) 会发生阻塞
单处理器 多任务(多线程)增加上下文切换,不会发生并发的访问共享资源
多处理器 单任务(单线程) 浪费CPU资源
多处理器 多任务(多线程) 多个线程之间会并发的访问共享资源
Java的线程机制是抢占式的,这表示调度机制会周期性的中断线程,将上下文切换到另一个线程,从而为每个线程都提供时间片,使得每个线程都会分配到数量合理的时间去驱动他的任务。协作式系统中,每个任务都会自动的放弃控制,这要求程序员要有意识地在每个任务中插入某种类型的让步语句(yeild)。
并发编程使我们可以将程序划分为多个分离的、独立运行的任务。通过多线程机制,这些独立任务(子任务)中的每一个都将由执行线程驱动,一个线程就是在进程中的一个单一的顺序控制流,因此,单个进程可以拥有多个并发执行的任务,但是你的程序使得每个任务都好像有其自己的CPU一样,其底层机制是切分CPU时间。
多线程比多任务更加有挑战。多线程是在同一个程序内部并行执行,因此会对相同的内存空间进行并发读写操作。这可能是在单线程程序中从来不会遇到的问题。其中的一些错误也未必会在单CPU机器上出现,因为两个线程从来不会得到真正的并行执行。然而,更现代的计算机伴随着多核CPU的出现,也就意味着不同的线程能被不同的CPU核得到真正意义的并行执行。
并发造成的问题:如果一个线程在读一个内存时,另一个线程正向该内存进行写操作,那进行读操作的那个线程将获得什么结果呢?是写操作之前旧的值?还是写操作成功之后的新值?或是一半新一半旧的值?或者,如果是两个线程同时写同一个内存,在操作完成后将会是什么结果呢?是第一个线程写入的值?还是第二个线程写入的值?还是两个线程写入的一个混合值?因此如没有合适的预防措施,任何结果都是可能的。而且这种行为的发生甚至不能预测,所以结果也是不确定性的。
本文探讨了并发编程的基本概念,包括多处理器环境下任务分配的优势,单处理器环境下并发的开销,以及多线程编程面临的挑战。文章还讨论了线程间的资源共享问题,并解释了在多核CPU环境下线程并行执行的重要性。
2673

被折叠的 条评论
为什么被折叠?



