知识大全 多线程的优点和代价

Posted 文件

篇首语:宁可枝头抱香死,何曾吹落北风中。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 多线程的优点和代价相关的知识,希望对你有一定的参考价值。

  尽管面临很多挑战 多线程有一些优点使得它一直被使用 这些优点是

  ● 资源利用率更好

  ● 程序设计在某些情况下更简单

  ● 程序响应更快

  资源利用率更好

  想象一下 一个应用程序需要从本地文件系统中读取和处理文件的情景 比方说 从磁盘读取一个文件需要 秒 处理一个文件需要 秒 处理两个文件则需要

秒读取文件A 秒处理文件A 秒读取文件B 秒处理文件B 总共需要 秒

  从磁盘中读取文件的时候 大部分的CPU时间用于等待磁盘去读取数据 在这段时间里 CPU非常的空闲 它可以做一些别的事情 通过改变操作的顺序 就能够更好的使用CPU资源 看下面的顺序

秒读取文件A 秒读取文件B + 秒处理文件A 秒处理文件B 总共需要 秒

  CPU等待第一个文件被读取完 然后开始读取第二个文件 当第二文件在被读取的时候 CPU会去处理第一个文件 记住 在等待磁盘读取文件的时候 CPU大部分时间是空闲的

  总的说来 CPU能够在等待IO的时候做一些其他的事情 这个不一定就是磁盘IO 它也可以是网络的IO 或者用户输入 通常情况下 网络和磁盘的IO比CPU和内存的IO慢的多

  程序设计更简单

  在单线程应用程序中 如果你想编写程序手动处理上面所提到的读取和处理的顺序 你必须记录每个文件读取和处理的状态 相反 你可以启动两个线程 每 个线程处理一个文件的读取和操作 线程会在等待磁盘读取文件的过程中被阻塞 在等待的时候 其他的线程能够使用CPU去处理已经读取完的文件 其结果就 是 磁盘总是在繁忙地读取不同的文件到内存中 这会带来磁盘和CPU利用率的提升 而且每个线程只需要记录一个文件 因此这种方式也很容易编程实现

  程序响应更快

  将一个单线程应用程序变成多线程应用程序的另一个常见的目的是实现一个响应更快的应用程序 设想一个服务器应用 它在某一个端口监听进来的请求 当一个请求到来时 它去处理这个请求 然后再返回去监听

  服务器的流程如下所述

while( server is active)     listen for request     process request

  如果一个请求需要占用大量的时间来处理 在这段时间内新的客户端就无法发送请求给服务端 只有服务器在监听的时候 请求才能被接收 另一种设计是 监听线 程把请求传递给工作者线程(worker thread) 然后立刻返回去监听 而工作者线程则能够处理这个请求并发送一个回复给客户端 这种设计如下所述

while(server is active)     listen for request     hand request to worker thread

  这种方式 服务端线程迅速地返回去监听 因此 更多的客户端能够发送请求给服务端 这个服务也变得响应更快

  桌面应用也是同样如此 如果你点击一个按钮开始运行一个耗时的任务 这个线程既要执行任务又要更新窗口和按钮 那么在任务执行的过程中 这个应用程 序看起来好像没有反应一样 相反 任务可以传递给工作者线程(word thread) 当工作者线程在繁忙地处理任务的时候 窗口线程可以自由地响应其他用户的请求 当工作者线程完成任务的时候 它发送信号给窗口线程 窗口 线程便可以更新应用程序窗口 并显示任务的结果 对用户而言 这种具有工作者线程设计的程序显得响应速度更快

  从一个单线程的应用到一个多线程的应用并不仅仅带来好处 它也会有一些代价 不要仅仅为了使用多线程而使用多线程 而应该明确在使用多线程时能多来的好处比所付出的代价大的时候 才使用多线程 如果存在疑问 应该尝试测量一下应用程序的性能和响应能力 而不只是猜测

  设计更复杂

  虽然有一些多线程应用程序比单线程的应用程序要简单 但其他的一般都更复杂 在多线程访问共享数据的时候 这部分代码需要特别的注意 线程之间的交互往往非常复杂 不正确的线程同步产生的错误非常难以被发现 并且重现以修复

  上下文切换的开销

  当CPU从执行一个线程切换到执行另外一个线程的时候 它需要先存储当前线程的本地的数据 程序指针等 然后载入另一个线程的本地数据 程序指针 等 最后才开始执行 这种切换称为 上下文切换 ( context switch ) CPU会在一个上下文中执行一个线程 然后切换到另外一个上下文中执行另外一个线程

  上下文切换并不廉价 如果没有必要 应该减少上下文切换的发生

  增加资源消耗

cha138/Article/program/Java/gj/201311/27296

相关参考

知识大全 基于线程池的匹配文件数量计算

   构建一个新的线程的代价还是有些高的因为它涉及与操作系统的交互如果你的程序创建了大量生存期很短的线程那就应该使用线程池一个线程池包含大量准备运行的空闲线程你将一个Ru

知识大全 Java多线程编程基础之线程和多线程

Java多线程编程基础之线程和多线程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  随着计算机技

知识大全 多线程从线程继承

    为创建一个线程最简单的方法就是从Thread类继承这个类包含了创建和运行线程所需的一切东西Thread最重要的方法是run()但为了使用run()必须对其进行过载或者覆蓋使其能充分按自己的吩咐

知识大全 多线程编程您不知道的5件事

   多线程编程向来不容易但很少有Java?开发人员能够忽视多线程编程和支持它的Java平台库我们临时学习线程在需要时向我们的工具箱添加新的技巧和技术以这种方式构建和运行

知识大全 强大的多线程和倒计时程序

  多线程技术是非常实用的技术特别是碰到有关运行多个任务的程序就只有多线程才能满足你的要求在以下程序中我所展示的是一个倒计时程序及利用Callable接口(不是Runnable接口)来返回一个你所要求

知识大全 java多线程notify和wait

java多线程之wait()notify()notifyAll()    wait()notify()notifyAll()不属于Thread类而是属于Object基础类也就是说每个对像都有wait(

知识大全 Heritrix的多线程ToeThread和ToePool

Heritrix的多线程ToeThread和ToePool  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一

知识大全 高级应用 java多线程设计模式详解之一

  线程的创建和启动    java语言已经内置了多线程支持所有实现Runnable接口的类都可被启动一个新线程新线程会执行该实例的run()方法当run()方法执行完毕后线程就结束了一旦一个线程执行

知识大全 Java多线程中run和start的区别

Java多线程中run和start的区别  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  区别调用

知识大全 Java的多线程-实现多线程及线程的同步

Java的多线程-实现多线程及线程的同步  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  一.实现