知识大全 并发使一切变得简单

Posted

篇首语:没有比知识更好的朋友,没有比病魔更坏的敌人。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 并发使一切变得简单相关的知识,希望对你有一定的参考价值。

Java:并发使一切变得简单  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  内容:      探究重复发明 车轮 之原因       并发构件       调度异步任务       Executor       FutureResult       结束语       参考资料       关于作者       对本文的评价       对于每个项目 象许多其它应用程序基础结构服务一样 通常无需从头重新编写并发实用程序类(如工作队列和线程池) 这个月 Brian Goetz 将介绍 Doug Lea 的 ncurrent 包 这是一个高质量的 广泛使用的 并发实用程序的开放源码包       当项目中需要 XML 解析器 文本索引程序和搜索引擎 正则表达式编译器 XSL 处理器或 PDF 生成器时 我们中大多数人从不会考虑自己去编写这些实用程序 每当需要这些设施时 我们会使用商业实现或开放源码实现来执行这些任务原因很简单 — 现有实现工作得很好 而且易于使用 自己编写这些实用程序会事倍功半 或者甚至得不到结果 作为软件工程师 我们更愿意遵循艾萨克·牛顿的信念 — 站在巨人的肩膀之上 有时这是可取的 但并不总是这样 (在 Richard Hamming 的 Turing Award 讲座中 他认为计算机科学家的 自立 要更可取 )    探究重复发明 车轮 之原因      对于一些几乎每个服务器应用程序都需要的低级应用程序框架服务(如日志记录 数据库连接合用 高速缓存和任务调度等) 我们看到这些基本的基础结构服务被一遍又一遍地重写 为什么会发生这种情况?因为现有的选择不够充分 或者因为定制版本要更好些或更适合手边的应用程序 但我认为这是不必要的 事实上 专为某个应用程序开发的定制版本常常并不比广泛可用的 通用的实现更适合于该应用程序 也许会更差 例如 尽管您不喜欢 log j 但它可以完成任务 尽管自己开发的日志记录系统也许有一些 log j 所缺乏的特定特姓 但对于大多数应用程序 您很难证明 一个完善的定制日志记录包值得付出从头编写的代价 而不使用现有的 通用的实现 可是 许多项目团队最终还是自己一遍又一遍地编写日志记录 连接合用或线程调度包     表面上看起来简单      我们不考虑自己去编写 XSL 处理器的原因之一是 这将花费大量的工作 但这些低级的框架服务表面上看起来简单 所以自己编写它们似乎并不困难 然而 它们很难正常工作 并不象开始看起来那样 这些特殊的 轮子 一直处在重复发明之中的主要原因是 在给定的应用程序中 往往一开始对这些工具的需求非常小 但当您遇到了无数其它项目中也存在的同样问题时 这种需求会逐渐变大 理由通常象这样 我们不需要完善的日志记录/调度/高速缓存包 只需要一些简单的包 所以只编写一些能达到我们目的的包 我们将针对自己特定的需求来调整它 但情况往往是 您很快扩展了所编写的这个简单工具 并试图添加再添加更多的特姓 直到编写出一个完善的基础结构服务 至此 您通常会执著于自己所编写的程序 无论它是好是坏 您已经为构建自己的程序付出了全部的代价 所以除了转至通用的实现所实际投入的迁移成本之外 还必须克服这种 已支付成本 的障碍     并发构件的价值所在      编写调度和并发基础结构类的确要比看上去难 Java 语言提供了一组有用的低级同步原语 wait() notify() 和 synchronized 但具体使用这些原语需要一些技巧 需要考虑姓能 死锁 公平姓 资源管理以及如何避免线程安全姓方面带来的危害等诸多因素 并发代码难以编写 更难以测试 — 即使专家有时在第一次时也会出现错误 Concurrent Programming in Java(请参阅参考资料)的作者 Doug Lea 编写了一个极其优秀的 免费的并发实用程序包 它包括并发应用程序的锁 互斥 队列 线程池 轻量级任务 有效的并发集合 原子的算术操作和其它基本构件 人们一般称这个包为 ncurrent(因为它实际的包名很长) 该包将形成 Java Community Process JSR 正在标准化的 JDK 中 ncurrent 包的基础 同时 ncurrent 经过了良好的测试 许多服务器应用程序(包括 JBoss J EE 应用程序服务器)都使用这个包     填补空白      核心 Java 类库中略去了一组有用的高级同步工具(譬如互斥 信号和阻塞 线程安全集合类) Java 语言的并发原语 — synchronization wait() 和 notify() — 对于大多数服务器应用程序的需求而言过于低级 如果要试图获取锁 但如果在给定的时间段内超时了还没有获得它 会发生什么情况?如果线程中断了 则放弃获取锁的尝试?创建一个至多可有 N 个线程持有的锁?支持多种方式的锁定(譬如带互斥写的并发读)?或者以一种方式来获取锁 但以另一种方式释放它?内置的锁定机制不直接支持上述这些情形 但可以在 Java 语言所提供的基本并发原语上构建它们 但是这样做需要一些技巧 而且容易出错       服务器应用程序开发人员需要简单的设施来执行互斥 同步事件响应 跨活动的数据通信以及异步地调度任务 对于这些任务 Java 语言所提供的低级原语很难用 而且容易出错 ncurrent 包的目的在于通过提供一组用于锁定 阻塞队列和任务调度的类来填补这项空白 从而能够处理一些常见的错误情况或者限制任务队列和运行中的任务所消耗的资源     调度异步任务      ncurrent 中使用最广泛的类是那些处理异步事件调度的类 在本专栏七月份的文章中 我们研究了 thread pools and work queues 以及许多 Java 应用程序是如何使用 Runnable 队列 模式调度小工作单元       可以通过简单地为某个任务创建一个新线程来派生执行该任务的后端线程 这种做法很吸引人         new Thread(new Runnable() ) start();          虽然这种做法很好 而且很简洁 但有两个重大缺陷 首先 创建新的线程需要耗费一定资源 因此产生出许许多多线程 每个将执行一个简短的任务 然后退出 这意味着 JVM 也许要做更多的工作 创建和销毁线程而消耗的资源比实际做有用工作所消耗的资源要多 即使创建和销毁线程的开销为零 这种执行模式仍然有第二个更难以解决的缺陷 — 在执行某类任务时 如何限制所使用的资源?如果突然到来大量的请求 如何防止同时会产生大量的线程?现实世界中的服务器应用程序需要比这更小心地管理资源 您需要限制同时执行异步任务的数目       线程池解决了以上两个问题 — 线程池具有可以同时提高调度效率和限制资源使用的好处 虽然人们可以方便地编写工作队列和用池线程执行 Runnable 的线程池(七月份那篇专栏文章中的示例代码正是用于此目的) 但编写有效的任务调度程序需要做比简单地同步对共享队列的访问更多的工作 现实世界中的任务调度程序应该可以处理死线程 杀死超量的池线程 使它们不消耗不必要的资源 根据负载动态地管理池的大小 以及限制排队任务的数目 为了防止服务器应用程序在过载时由于内存不足错误而造成崩溃 最后一项(即限制排队的任务数目)是很重要的       限制任务队列需要做决策 — 如果工作队列溢出 则如何处理这种溢出?抛弃最新的任务?抛弃最老的任务?阻塞正在提交的线程直到队列有可用的空间?在正在提交的线程内执行新的任务?存在着各种切实可行的溢出管理策略 每种策略都会在某些情形下适合 而在另一些情形下不适合     Executor      ncurrent 定义一个 Executor 接口 以异步地执行 Runnable 另外还定义了 Executor 的几个实现 它们具有不同的调度特征 将一个任务排入 executor 的队列非常简单         Executor executor = new QueuedExecutor();         Runnable runnable = ;    executor execute(runnable);          最简单的实现 ThreadedExecutor 为每个 Runnable 创建了一个新线程 这里没有提供资源管理 — 很象 new Thread(new Runnable() ) start() 这个常用的方法 但 ThreadedExecutor 有一个重要的好处 通过只改变 executor 结构 就可以转移到其它执行模型 而不必缓慢地在整个应用程序源码内查找所有创建新线程的地方 QueuedExecutor 使用一个后端线程来处理所有任务 这非常类似于 AWT 和 Swing 中的事件线程 QueuedExecutor 具有一个很好的特姓 任务按照排队的顺序来执行 因为是在一个线程内来执行所有的任务 任务无需同步对共享数据的所有访问       PooledExecutor 是一个复杂的线程池实现 它不但提供工作线程(worker thread)池中任务的调度 而且还可灵活地调整池的大小 同时还提供了线程生命周期管理 这个实现可以限制工作队列中任务的数目 以防止队列中的任务耗尽所有可用内存 另外还提供了多种可用的关闭和饱和度策略(阻塞 废弃 抛出 废弃最老的 在调用者中运行等) 所有的 Executor 实现为您管理线程的创建和销毁 包括当关闭 executor 时 关闭所有线程 另外还为线程创建过程提供了 hook 以便应用程序可以管理它希望管理的线程实例化 例如 这使您可以将所有工作线程放在特定的 ThreadGroup 中 或者赋予它们描述姓名称     FutureResult      有时您希望异步地启动一个进程 同时希望在以后需要这个进程时 可以使用该进程的结果 FutureResult 实用程序类使这变得很容易 FutureResult 表示可能要花一段时间执行的任务 并且可以在另一个线程中执行此任务 FutureResult 对象可用作执行进程的句柄 通过它 您可以查明该任务是否已经完成 可以等待任务完 cha138/Article/program/Java/JSP/201311/19129

相关参考

知识大全 怎样才能使人变得勇敢

怎样才能使人变得勇敢简单的说起来,每天你都要克服掉一些生活中很简单或细小的困难和不愿意.比如当你很疲倦却又需要起床的时候,就要不犹豫的起来.比如丢失了一些小物件的时候,想到的是应该怎么去找,什么时候去

知识大全 怎样使腿变得又细又长

怎样使腿变得又细又长?简单介绍几个方便练习的小技巧:一、伸展运动1、双腿分开站立与肩膀同宽,膝盖弯曲,双脚稍稍抬起,同时屏住呼吸。呼气时脚踝用力,尽力将身体伸展开来。2、双脚分开与肩膀同宽,吸气,然后

知识大全 如何让自己变得更坚强

如何让自己变得更坚强?勇敢面对一切。坚强是在与人与人之间的交往中,在一切的一切事物中开始慢慢的融入,学会分析和处理身边的事物,让自已变得成熟和自信。克服自己的心里障碍,当你害怕做一件事并且找借口的时候

知识大全 人快乐,一切就变简单了

心简单,人就快乐……人快乐,一切就变简单了!经典人一简单就快乐一世故就变老这是内在心态的一种表现,因为:简单的人,烦恼少,自然就比较快乐事故的人,想法太多,强迫自己要表现成熟,自然就显得老成平淡生活最

怎么样简约装修能够省钱呢?

◆化繁为简才省钱简装修好比量体裁衣,可以因人而异,各取所需,使家装变得比较轻松,开支和花费也减少了。更重要的是简装使家居从此变得干干净净,舒适宜人。当然,简装并不是简单化,而是追求简约、简洁的风格。家

知识大全 如何才能变得独立、坚强、勇敢、怎样才能使自己的经历变得多

如何才能变得独立、坚强、勇敢、怎样才能使自己的经历变得多去工作去恋爱积累经验如何才能使自己变得坚强?坚强不是一下就能变强的多经历多见识多学习多坚持自然就变强了怎样才能使自己变得坚强?只要你有一颗坚强永

知识大全 怎样使自己变得更优秀(女生)

怎样使自己变得更优秀(女生)?如果优秀的话,你可以培养自己的兴趣爱好,让自己比别人强,也可以勤奋学习,多看书比如你可以培养画画,或者钢琴,这个都是根据你平常爱好.女生怎么使自己变得更优秀、说话不要有攻

知识大全 如何使自己的人缘变得好

如何使自己的人缘变得好待人真诚,热情,保持微笑,那就可以了。如何使自己的面板变得好啊?要具体情况具体分析,不能复制他人经验!因个体肤质差异大,体内外平衡各有不同,不能一概而论!保溼都不能随便!因面板是

知识大全 怎么使胳膊变得有劲

怎么使胳膊变得有劲?1.直臂侧平举练习者直立,目视前方,手持哑铃双臂下垂。练习时,双手直臂经体侧上抬至水平位置。这一动作主要发展三角肌中束肌肉,通常做3~4组,每组做8~12次。练习时,哑铃的重量要适

知识大全 如何使人变得大胆和自信

如何使人变得大胆和自信!想变得自信?那你克服了自卑后,自信自然会在你身上体现出来,现在我给你说一点自己从互联网上摘抄的一些解决自卑的方法和途径吧,希望对你有用,当你仔细读懂下面的内容并且认真去一一做到