多线程模型真的能够提高效率吗?
2009-02-23 15:13
218 查看
原文地址http://blog.csai.cn/user1/16236/archives/2007/11679.html
早段时间在网上看到一篇文章,其中就写了使用多线程模型实现文件的快速搜索。由此使我一直在考虑,多线程模型真的能够提高应用程序的效率吗?如果不能,那么多线程模型能干什么呢?
很多程序员一谈到提高应用程序效率的问题,就会想到多线程模型。就如我所看到的那篇文章一样,希望能够通过多线程模型达到在文件系统中快速搜索文件的目的。然而不幸的是,在很多应用场景中,多线程模型不仅不能提高效率,还会带来很多的负面问题。尤其是对于需要反复访问临界资源的应用场景中,由于同步与线程调度所引起的效率问题,会使得应用程序的运行效率与数据吞吐量大打折扣。
首先就是并发控制带来的效率问题。多线程模型必须现实地面对并发控制问题,否则将会出现数据完整性的严重后果,甚至引发悲观并发控制的经典问题:死锁。通常情况下,应用程序都是使用操作系统提供的加锁机制实现并发控制,但是这些加锁机制都是非常耗费资源的,频繁的加锁与释放会大大降低应用程序的执行效率。乐观并发控制可以有效地避免加锁机制的效率损耗,提高系统的并发度,但是它的应用范围十分有限,因为乐观并发控制首先假设应用程序很少出现并发冲突。关于悲观并发控制与乐观并发控制,可以参考我的上一篇文章。您或许会认为,可以使用双检查加锁优化惯用法来减小加锁开销,事实上这种惯用法确实可以大幅度提高加锁效率,但双检查加锁优化并不能100%地用于所有的编译系统,至少我知道在Java编译系统中可能会出现问题(比如编译系统的优化选项使得用作标记的类级静态变量被优化,导致第一次检查失败)。
其次就是线程调度引起的效率问题。假设现在有两个线程A和B,它们执行着简单的逻辑:A获得锁(加锁),B阻塞,A执行操作,之后A释放锁,B获得锁,A继续请求锁,因被B获得锁而阻塞,B执行操作,如此反复。当一个线程获得锁以后,会导致另一个线程进入阻塞状态。在这样的操作多次反复的情况下,线程调度的开销是非常可观的。Windows系统是抢占式操作系统,与实时操作系统不一样,在底层,一个处理器在一个时间点只能执行一个线程,这是一种微观串行,从宏观上来看,似乎是多个任务同时执行,实现了宏观并行。为了真正达到并行处理,或者应该使用多处理器的体系结构。
再次就是多线程模型的移植性很差,这是因为,并非所有的操作系统都支持线程模型,因此使用多线程模型的应用程序将会变得很难移植。
为了解决这些问题,几乎所有操作系统都提供事件的异步处理机制,用来实现并发处理,并且避免由于多线程模型带来的额外系统开销。
您可能会觉得,既然多线程模型在系统开销上很大,那为什么现在很多网络下载软件使用多线程模型可以提高下载速度呢?我想,下载软件的速度瓶颈应该不是在并发控制与线程调度上,而是在网络速度上,这两个值是在不同数量级上的。
对于像高性能服务器这样的应用程序而言,多线程模型带来的弊端不可忽视,它直接影响到整个系统的执行效率和移植性。因此,现代化的高性能服务器都是使用单线程,或者使用较少的线程数,通过异步事件处理来降低系统开销,提高并发性,从而高效地为客户端服务的。
相关文章推荐
- 能够提高开发效率的Eclipse实用操作(1)
- 一些能够提高程序员办公效率的办公桌
- 为何多线程就能提高Java程序的执行效率
- 能够提高开发效率的Eclipse实用操作
- 能够提高开发效率的Eclipse实用操作(2)
- JAVA多线程,真的提高了效率吗?
- 能够提高开发效率的Eclipse实用操作
- lucene-利用内存中索引和多线程提高索引效率
- 通过数学模型提高效率:求1/1!-1/3!+1/5!-1/7!+...+(-1)^n+1/(2n-1)!
- 模型驱动SOA帮助提高开发团队效率
- 多线程不是为了提高效率,而是不必等待
- java多线程(七)提高锁的效率——使用读写锁
- C++ windows多线程 线程描述了进程内代码的执行路径。进程中同时可以有多个线程在执行,为了使他们能够同时运行,操作系统为每个线程轮流分配CPU时间片,为了充分地利用CPU提高软件产品的性能,一
- lucene-利用内存中索引和多线程提高索引效率
- java中使用多线程不能明显提高程序效率的一些原因
- EXITS等价替换提高效率//////数据库三种模型与RDBMS关系
- java多线程不单单只是提高程序的执行效率
- 能够提高开发效率的Eclipse实用操作-第二篇
- 多线程为什么可以提高效率
- 多线程写文件是否提高效率?