相关读书笔记列表
NO.48 对共享可变数据的同步访问
同步,不仅可以阻止一个线程看到对象处于不一致的状态中,它还可以保证通过一系列看似顺序执行的状态转变序列,对象从一种一致的状态变迁到另一种一致的状态。
synchronized关键字可以保证在同一时刻,只有一个线程在执行一条语句,或者一段代码块。java语言保证读或写一个变量是原子的,除非这个变量的类型是long或double.
java的内存模型决定,为了在线程之间可靠地通信,以及为了互斥访问,对原子数据的读写进行同步是需要的。看一个可怕的例子:
对其改进,只需要在generateSerialNumber的声明中增加synchronized修饰符即可。
为了终止一个线程,一种推荐的做法是让线程轮询某个域,该域的值如果发生变化,就表明此线程就应该终止自己。下面的例子就是这个思路,但在同步出了问题。
对其改进如下:
另一种改进是,将stopRequested声明为volatile,则同步可以省略。
再来看迟缓初始化(lazy initialization)问题,双重访问模式并不一定都能正常工作,除非被共享的变量包含一个原语值。看例子:
最容易的修改是省去迟缓初始化:
或者使用正确的同步方法,但可能增加少许的同步开销:
按需初始化容器模式也不错,但是它只能用于静态域,不能用于实例域。
简而言之,无论何时当多个线程共享可变数据的时候,每个读或写数据的线程必须获得一把锁。如果没有同步,则一个线程所做的修改就无法保证被另一个线程所观察到。
NO.51 不要依赖于线程调度器
不能让应用程序的正确性依赖于线程调度器。否则,结果得到的应用程序既不健壮也不具有可移植性。作为一个推论,不要依赖Thread.yield或者线程优先级。这些设施都只是影响到调度器,它们可以被用来提高一个已经能够正常工作的系统的服务质量,但永远不应用来“修正”一个原本并不能工作的程序。
编写健壮的、响应良好的、可移植的多线程应用程序的最好办法是,尽可能确保在任何给定时刻只有少量的可运行线程。这种办法采用的主要技术是,让每个线程做少量的工作,然后使用Object.Wait等待某个条件发生,或者使用Thread.sleep睡眠一段时间。
NO.52 线程安全性的文档化
每个类都应该清楚地在文档中说明它的线程安全属性。在一个方法的声明中出现synchronized修饰符,这是一个实现细节,并不是导出的API文档的一部分。
一个类为了可被多个线程安全地使用,必须在文档中清楚地说明它所支持的线程安全性级别。
非可变性(immutable)-这个类的实例对于其它客户而言是不变的,不需要外部的同步。参见13条。
线程程安全的(thread-safe)-这个类的实例是可变的,但是所有的地方都包含足够的同步手段,这些实例可以被并发使用无需外部同步。
有条件的线程安全(conditionally thread-safe)-这个类(或关联的类)包含有某些方法,它们必须被顺序调用,而不能受到其它线程的干扰,除此之外,这种线程安全级别与上一种情形相同。为了消除被其他线程干扰的可能性,客户在执行此方法序列期间,必须获得一把适当的锁。如HashTable或Vector,它们的迭代器要求外部同步。如:
线程兼容的(thread-compatible)-在每个方法调用的外围使用外部同步,此时这个类的实例可以被安全的并发使用。如ArrayList或HashMap
线程对立的(thread-hostile)这个类不能安全地被多个线程并发使用,即使所有的方法调用都被外部同步包围。通常情况下,线程对立的根源在于,这个类的方法要修改静态数据,而这些静态数据可能会影响到其它的线程。
对于有条件的线程安全类,在文档中指明“为了允许方法调用序列以原子方式执行,哪一个对象应被锁住”.
NO.53 避免使用线程组
除了线程、锁和监视器之外,线程系统还提供了一个基本的抽象,即线程组(thread-group)。然而线程组并没有提供太多有用的功能。
一个例外是,当线程组中的一个线程抛出一个未被捕获的异常时,ThreadGroup.uncaughtException方法会被自动调用。“执行环境”使用这个方法,以便用适当的方式来响应未被捕获的异常。
NO.54 保护性地编写readObject方法
编写一个类的readObject方法,相当于编写一个公有的构造函数,无论给它传递一个什么样的字节流,它都必须产生一个有效的实例。下面是缩写健壮的readObject方法的指导原则:
①对于对象引用域必须保持为私有的类,对“将被保存到这些域中的对象”进行保护性拷贝。非可变类的可变组件就属于这一类别。
②对于具有约束条件的类,一定要检查约束条件是否满足,如果不满足的话,则抛出一个InvalidObjectException异常。这些检查应跟在所有的保护性拷贝之后。
③如果在对象图被反序列化之后,整个对象图必须都是有效的,则应该使用ObjectInputValidation接口。
④无论是直接方式还是间接方式,都不要调用类中可被改写的方法。
⑤readResolve方法有可能取被用来替代保护性的readObject方法。
不严格地说,readObject是一个“用字节流作为唯一参数”的构造函数。当面对一个人工伪造的字节流的时候,readObject产生的对象会违反它所属的类的约束条件。初步的方法,是在readObject方法进行约束性检查,如下例:
对上述的防范仍可进行攻击:伪造一个字节流,这个字节流以一个有效的Period实例所产生的字节流作为开始,然后附加上两个额外的引用,指向 Period实例中的两个内部私有Date域,攻击者通过引用攻击内部域。所以,当一个对象被反序列化的时候,对于客户不应该拥有的对象引用,如果哪个域包含了这样的对象引用,则必须要做保护性拷贝,这是非常重要的。如下例:
NO.57 必要时提供一个readResolve方法
无论是 singleton,或是其他实例受控(instance-controlled)的类,必须使用readResolve方法来保护“实例-控制的约束 ”。从本质上来讲,readResovle方法把一个readObject方法从一个事实上的公有构造函数变成一个事实上的公有静态工厂。对于那些禁止包外继承的类而言,readResolve方法作为保护性的readObject方法的一种替代,也是非常有用的。
如下sigleton类:
如果Elvis实例序列化接口,则下面的readResolve方法足以保证它的sigleton属性。
不仅仅对于singleton对象是必要的,readResolve方法对于所有其它的实例受控类(如类型安全枚举类型)也是必需的。
readResolve方法的第二个用法是,就像在第56条建议的那样,作为保护性的readObject方法的一种保守的替代选择。此时,第56条中的readObject方法可以下例的例子替代:
对于那些允许继承的类,readResolve方法可能无法替代保护性的readObject方法。如果超类的readResolve方法是final 的,则使得子类实例无法被正常地反序列化。如果超类的readResolve方法是可改写的,则恶意的子类可能会用一个方法改写它,该方法返回一个受损的实例。
结束语:花了好几个月断断续续地把这本书看完了,期间做了好几个项目,忙了一段时间,看书的进度有些拖延,现在看之前整理的笔记都有点遗忘了,不过没关系,以后可以返回去看看,温故而知新嘛。。。
相关推荐
"Effective Java读书笔记" Effective Java是一本关于Java编程语言的经典书籍,本笔记主要总结了Java语言的发展历程、静态工厂方法的应用、构造器模式的使用等重要知识点。 一、Java语言的发展历程 Java语言的发展...
《Effective Java》是Java开发领域的经典著作,作者Joshua Bloch深入浅出地阐述了编写高效、健壮的Java代码的技巧和最佳实践。以下是对该书部分内容的详细解释: 1. **产生和销毁对象** - Item1:静态工厂方法相比...
以下是对《Effective Java》笔记中可能涉及的关键知识点的详细解读: 1. **单例模式**:书中强调了如何正确实现单例模式,推荐使用`enum`来创建线程安全且唯一的实例,避免传统双重检查锁定的潜在问题。 2. **构造...
Effective Java 读书笔记 - 枚举与注解 本文总结了Effective Java 中关于枚举与注解的知识点,涵盖了枚举类型的优点、使用指南、避免使用 int 常量、使用 EnumSet 和 EnumMap 等。 枚举类型的优点 枚举类型提供了...
读书笔记:Effective Java中文版第3版笔记
《Effective Java》是Java...以上仅是《Effective Java》一书中部分核心知识点的概述,实际的读书笔记中会更详细地解释这些概念,并给出具体的示例代码。通过深入学习和实践,开发者可以极大地提升其Java编程的水平。
读书笔记:Effective Java中文版第二版示例、笔记
《Effective Java》是一本经典Java编程指南,作者是Joshua Bloch,这本书深入探讨了如何编写高质量、高效、可维护的Java代码。以下是对压缩包中各章节主要知识点的详细阐述: 1. **第2章 创建和销毁对象** - 单例...
读书笔记:Effective Java中文版学习项目
读书笔记:Java练习包括《Java编程思想》《算法》《Effective Java》等
读书笔记:Effective Java中文版 第2版
读书笔记:Effective Java中文版第二版示例代码
读书笔记:Effective Java 中文版(2版和3版)
读书笔记:读Effective Java中文版第3版阅读源码测试案列
读书笔记:Effective Java 中文版(第2版)总结 (美)Joshua Bloch 著
### Effective Java读书笔记(上) #### 第一章 引言 本书主要针对Java开发者提供了大量实用的编程指导建议,帮助读者提升代码质量和程序性能。在本章节中,我们将重点介绍对象的创建与销毁,以及一些重要的设计...
读书笔记:Effective.Java中文版(第3版)
除了课程内容,阅读官方文档、经典教材如《Head First Java》、《Effective Java》等,以及观看开源项目和在线教程,可以帮助巩固理论知识,提升实践能力。 总之,Java学习笔记旨在为初学者提供全面的学习路径,从...
“新建文本文档.txt”可能是一个简单的文本文件,用于记录学习过程中的笔记或者资源链接,或者可能是教程中的一部分内容,具体用途需打开文件查看。 总的来说,这份“Java学习PDF”是Java初学者宝贵的参考资料,...