- 浏览: 139871 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
邪恶八进制:
译的还不错,其实简单说、JPA三种继承映射体系如下:1.参照父 ...
[译文]JPA的实施模式:映射继承的层次体系 -
mondayw:
卓越上有售,地址:http://www.amazon.cn/m ...
翻译的第一本书出版了 -
黑暗浪子:
哪里有订?
翻译的第一本书出版了 -
mondayw:
不好意思,没有测试过,我以为这只是示范性的代码而已。
[译文]Java EE 6中的依赖注入——第1部分(二) -
jimmy.shine:
不知道你有无测试过这范例程序,在JBoss 6.0M2中,程序 ...
[译文]Java EE 6中的依赖注入——第1部分(二)
原文:Some Java Concurrency Tips
作者:Carol McDonald
出处:http://weblogs.java.net/blog/caroljmcdonald/archive/2009/09/17/some-java-concurrency-tips
这是来自Joshua Bloch、Brian Goetz和其他人的一个关于一些并发技巧的汇总。
首先选择不可变的对象/数据
不可变对象(immutable object)在构建之后就不会改变了,不可变对象更简单、安全,不需要锁,并且是线程安全的。为了使得不可变对象无需提供setter/mutator方法,把域修饰成private final的,并可防止其子类别化。如果不可选择不变性,那么限制可变的状态,越少的可变状态意味着越少的协调配合。在任何实际可行的情况下把域声明成final的,final域比可变域要简单得多。
在线程共享可变数据的时候,每个读线程或者写线程都必须要协调对数据的访问,未能同步共享的可变数据可能会导致原子性的失败、竞争条件、不一致的状态,以及其他形式的非确定性。这些不确定的问题都是最难以调试的。
使并发交互只在明确定义的地方发生,减少共享数据,考虑复制而不是共享。
Web应用的线程风险
一个Servlet的get、post、service方法能够同时被多个客户端调用,多线程Servlet实例和静态变量是共享的,因此如果是可变的话,那么访问必须加以协调。Servlet是典型的生命期长且被线程高频度加载的对象,如果过分同步的话性能会受影响,或者尽量共享不可变(final)数据,或者尝试完全不共享,请求参数和局部变量会更安全。
保持锁定的时间尽可能的短
在同步区内完成尽可能少的工作,把不需要加锁的代码放到同步代码块之外,特别是如果这些代码非常耗时的话!
Lock接口比使用同步代码块提供了更详尽的锁定操作,其有一个好处是如果锁是不可用的话,则不会导致阻塞。你应该只有在需要的时候才获取锁来读取或者写入共享的数据,并在一个finally子句内部解锁,以确保锁被释放。下面是一个使用ReentrantReadWriteLock的例子:
一种减少保持锁定的时间的做法是锁分拆或者锁分离,该方法是为各个状态变量使用不同的锁而不是使用单个锁,这减小了锁的粒度,提供了更好的可伸缩性,但必须要按照规则顺序来取用锁,否则会有死锁的危险。
首先选择executor和task而不是thread
使用Java并发工具Executor框架(Java Concurrency Utilities Executor Framework)而不是直接使用thread来工作。Executor服务把任务的提交从执行策略中分离出来,从可运行任务的角度来考虑,由executor服务来执行这些任务。
executor可以被直接创建或者是通过使用Executors类的工厂方法来创建:
现在给出一个使用Executor、Executors和ExecutorService类的例子:
这个例子是一个web service类,该类使用一个固定的线程池来处理多路同时传入的连接(connection),固定线程池使用返回一个ExecutorService对象的Executors类的newFixedThreadPool方法来初始化,收到的连接通过调用ExecutorService类型的pool对象的execute方法来处理,给该方法传入一个Runnable对象,Runnable对象的run方法处理连接,当run方法执行完成时,线程会被自动返还给线程池。如果有连接进来但所有的线程都已正被使用的话,那么主循环将会阻塞直到有一个线程被释放。
首先选择并发实用工具而不是wait和notify操作
每次只要你打算使用wait和notify方法时,查看一下java.util.concurrent中是否有你所需要的类,并发集合总是会提供诸如List、Queue和Map一类的标准集合接口的高性能并发实现。
BlockingQueue是带有扩展的阻塞方法的并发对象,这些方法会一直等待(或者阻塞),直到检索的元素变为可用的,或者是存储空间变为可用的时才继续执行。
生产者消费者模式
阻塞队列对生产者消费者模式(Producer Consumer Pattern)来说很有用,在该模式中,生产者线程把工作项目加入队列而消费者线程则把工作项目从队列中取出并进行处理。以下是一个被多个线程使用的记录器的消费者模式(Consumer Pattern)例子:
下面是使用logger的生产者(Producer)的例子,一个新的ArrayBlockingQueue被实例化以传递给logger的构造方法,在run方法中,信息被放入队列中以进行记录,如果队列满了的话,则放入操作会被阻塞直到logger已把队列中的消息取走才继续。
同步器
同步器是一些用来帮助线程间的协调访问的对象,最常用的同步器是倒计数锁存器(CountDownLatch)和信号量(Semaphore),同步器的使用可以消除大多数wait或者notify方法的使用。
下面是一个使用信号量来控制资源池访问的例子,多个线程可以请求使用一个资源,并在完成使用后把它交还。
在构造方法中,我们创建了一个新的信号量,信号量的大小与我们正在创建的资源池的大小相同。
在getResource()方法中,信号量的aquire方法被调用,尝试取得使用资源的许可,如果有资源可用的话,则该方法会有返回,然后会从池中返回一个资源。如果所有的资源都正在使用当中的话,则aquire方法的调用会阻塞,直到另一个线程调用该信号量的release方法时才继续执行。当某个线程完成资源的使用时,该资源会被返还给池,然后release方法会被调用。aquire和release方法都可以看作是原子操作。
多线程的延迟初始化需要一些技巧
当多个线程共享一个延迟初始化的域时,对该域的访问必须是同步的,否则可能会导致一些非确定性的错误出现。
首先选择正常的初始化
不要使用延迟初始化,除非对象或者域的初始化代价昂贵且不经常使用。通常情况下,正常的初始化是最好的;) 下面是一个线程安全的单例(singleton)预先初始化的例子,私有的final实例域和私有的构造方法使得该单例是不可变的。
如果基于静态域的性能问题而需要使用延迟加载的话,则使用按需初始化持有者模式(initialize-on-demand holder pattern),该模式利用了类直到被使用时才会初始化这一担保:
参考资料和更多信息:
Effective Java,第二版,Joshua Bloch著
Java Concurrency in Practice,Brian Goetz著
Robust and Scalable Concurrent Programming: Lessons from the Trenches
发表评论
-
[译文]技巧:防范代码的终结器漏洞
2011-08-02 11:11 743你的Java代码有可能会因终结操作带来的漏洞而易受到攻击,了解 ... -
[译文] 一种减少多线程Java应用的工作队列中的竞争和开销的方法
2011-06-21 10:08 986许多的服务器应用,比如说Web服务器、应用服务器、数据库服务器 ... -
[译文]Java SE 7带来更好的资源管理:不仅仅是语法糖
2011-06-18 19:55 775本文介绍了Java Platform, Standard Ed ... -
[译文]双重检查锁定和单件模式
2011-05-06 11:50 840所有的编程语言都会有分享一些它们的惯用技法,其中的 ... -
RJC501:为周转期付出的代价有多大?
2011-04-18 16:43 809通过重载Java类(Reloading Java ... -
RJC401:HotSwap和JRebel——幕后的故事
2011-04-11 16:31 1023在本文中,我们会回顾类在没有动态类加载器情况下的重载方式;我们 ... -
RJC301:Web开发——Tomcat、GlassFish、OSGi、Tapestry等服务器和框架中的Classloader
2011-04-04 15:26 948在本文中,我们会回顾真实的服务器、容器和框架是如何使用动态的类 ... -
RJC201:ClassLoader的泄漏是如何发生的?
2011-03-28 19:58 866你如果使用Java编程已有一段时间的话,那么你就会知道内存泄漏 ... -
jQuery的.bind()、.live()和.delegate()之间的区别
2011-03-19 22:01 831.bind()、.live()和.delegate()之间的 ... -
示例:JavaScript中的后续传递风格
2011-03-19 21:57 830本文介绍了CPS所扮演的两种角色——作为JavaScript中 ... -
[译文]开发者见解系列,第3部分:编写代码的步骤(下)
2010-07-27 22:11 878原文:The Developer Insight ... -
[译文]开发者见解系列,第3部分:编写代码的步骤(上)
2010-07-27 22:05 1116原文:The Developer Insight Series ... -
[译文]开发者见解系列,第2部分:谈谈编码(下)
2010-07-14 22:31 854原文:The Developer Insight Series ... -
[译文]开发者见解系列,第2部分:谈谈编码(上)
2010-07-14 22:26 1078原文:The Developer Insight Series ... -
[译文]开发者见解系列,第1部分:编写傻瓜代码——来自四位首席Java开发者的建议(下)
2010-06-28 12:32 828原文:The Developer Insight Series ... -
[译文]开发者见解系列,第1部分:编写傻瓜代码——来自四位首席Java开发者的建议(上)
2010-06-28 12:25 1412原文:The Developer Insight Series ... -
[译文] Java EE 6中的DataSource资源的定义
2010-05-20 12:29 1931原文:DataSource Resource Definiti ... -
[译文] Java Applets和ASP.net——你可让他们玩到一起吗?
2010-05-13 18:01 1688原文:Java Applets, ASP.net - Can ... -
[译文]使用Java编写你的第一个Google Wave机器人(下)
2010-01-25 21:03 1060原文:Write Your First Google Wave ... -
[译文]使用Java编写你的第一个Google Wave机器人(上)
2010-01-25 21:02 1323原文:Write Your First Google Wave ...
相关推荐
java并发底层的一些概念、原理。 java5、java6中常用并发类、并发集合的属性和使用方法。
毕业论文的专业译文,计算机专业,关于java堆的一些内容。中英文全。
本资源原文为java-for-Anylogic-user英文版,即面向Anylogic用户的Java开发,本人纯手工翻译,讲述以拖放方式以外的编程思路,对于建立复杂系统有很大帮助。这是一个信息论,可以在模型中进行数据操作以及智能体的...
JSP(JavaServer Pages)是一种基于Java的脚本技术。是由Sun Microsystems公司倡导、许多公司参与一起建立的一种动态网页技术标准。JSP技术有点类似ASP技术,它是在传统的网页HTML文件(*.htm,*.html)中插入Java程序...
译文:Fork and Join: Java Can Excel at Painless Parallel Programming Too!(Fork and Join Java也可以轻松地编写并发程序)
在今后的软件设计中无论使用Clojure语言,还是坚持使用Java语言,Clojure语言都将与java做比较,哪种是设计软件的最佳方式。 Clojure语言是一个JVM(包括Groovy,Jython和JRuby等语言)的新语言,它提供了活力,...
Disruptor它是一个开源的并发框架,并获得2011 Duke’s 程序框架创新奖,能够在无锁的情况下实现网 络的Queue并发操作。本文是Disruptor官网中发布的文章的译文(现在被移到了GitHub)。
计算机类专业毕业设计外文翻译的原文及译文。已经排版,下载即用。
JAVA外文文献+翻译.pdf
Generics_in_the_Java_Programming_Language的中文译文
java2007【搜狗文档翻译_译文_英译中】1
关于java的外文文献中英文对照都有
外文翻译—Java(译文+英文)
外文翻译—Java(译文+英文).doc
外文翻译—Java(译文-英文).doc
有关java,jsp类论文可用的英文论文及中文译文,两个文件一个是英文原文,一个是翻译
用WinAlign将译文批量导入记忆库的操作方法。
JAVA/JSP方面通用的英文参考文献及翻译
java3d_API中文版译文,其中有一部分是java3d_programming的译文,java3d中文版学习好好资料
中庸全文及译文.pdf