《Effective Java》第二版学习笔记之并发编程。

第66条 同步访问共享的可变数据

  * 关键字synchronized可以保证在同一时刻只有一个线程可以执行某个方法或代码块。

  * Java语音规范保证对一个变量的读操作或者写操作是原子性(atomic,注意 i++是非原子性的,64位的long型或double型变量的读写操作也是非原子性的),但并不保证一个线程写入的值对另一个线程是可见的。

  * 避免使用Thread.stop()方法,而是采用轮询(poll)机制来终止一个线程。

  * 如果只需要线程间的交互通信,而不需要互斥,可以使用volatile关键字。

 

第67条 避免过度同步

  * 为了避免活性失败和安全性失败,在一个被同步的方法或者代码块中,永远不要放弃对客户端的控制(避免在同步区域调用不可信代码,否则容易造成死锁、异常等问题)。

  * 在同步代码块内做尽可能少的事情。

第68条 executor 和 task 优先于线程

  * Executor service 可以等待完成一项特殊的任务再继续执行,也可以优雅的完成终止(利用awaitTerminalTermination方法),或可以在完成这些任务后逐个的获取这些任务的结果(利用ExecutorCompletionService)等。

  * 对于轻载的服务器,Executors.newCachedThreadPool通常是个不错的选择;对于高负载的服务器,最好使用Executors.newFixedThreadPool

  * 尽量不要编写自己的工作队列和直接使用线程;现在关键的抽象不再是Thread,而是工作单元(任务,task)。

  * Timer只有一个线程来执行任务,如果唯一的线程抛出了未被捕获的异常,任务就会终止。ScheduledThreadPoolExecutor 支持多个线程,并可以优雅的从抛出未受检异常的任务中恢复。

第69条 并发工具优先于wait和notify

  * 几乎没有任何理由再使用wait和notify了。

    但并不是说不需要掌握,如维护旧代码可能还是需要了解的,此种情况下务必确保是利用标准的模式从while循环内部调用wait。一般情况下优先使用notifyAll而不是notify。

  * 使用高级工具:

    执行器框架(Executor Framework)、并发集合(Concurrent Collection)、同步器(Synchronizer,如CountDownLatch、Semaphore、CyclicBarier和Exchanger等)。

第70条 线程安全性的文档化

  * 线程安全的级别:

    (1)不可变的(immutable):类的实例是不可变的(如String、Long、BigInteger等)。

    (2)无条件的线程安全(unconditionally thread-safe):类的实例可变,但有着足够的内部同步(如Random、ConcurrentHashMap。

    (3)有条件的线程安全(conditionally thread-safe):除了有些方法为了安全的并发使用外部同步之外,与无条件的线程安全级别相同(如 Collections.synchronized 包装返回的集合,它们的迭代器要求外部同步)。

    (4)非线程安全(not thread-safe):需外部同步(如ArrayList、HashMap等)。

    (5)线程对立(thread hostile):这个类不能安全的被多个线程并发的使用,即使所有的方法都被外部同步包围。线程对立的根源通常在于,没有同步的修改静态数据。

  * 为了避免拒绝服务攻击,应当使用一个私有锁对象(private lock object)来代替同步方法。私有锁对象只能用在无条件的线程安全类上,特别适合于专门为继承而设计的类。

第71条 慎用延迟初始化

  * 正常的初始化优先于延迟初始化。

  * 如果出于性能的考虑而需要对静态域使用延迟初始化,就使用 lazy initiation holder class 模式:

  1. private static class FieldHolder {
  2. static final FieldType field = computeFieldValue();
  3. }
  4.  
  5. static FieldType getType() {
  6. return FieldHolder.field;
  7. }

  * 如果出于性能的考虑而需要对实例域使用延迟初始化,就使用双重校验锁:

  1. // volatile 很重要,保证可见性
  2. private volatile FieldType field;
  3.  
  4. FieldType getField() {
  5. FieldType result = field;
  6. if (result == null) {
  7. synchronized(this) {
  8. result = field;
  9. if (result = null) {
  10. field = result = computeFieldValue();
  11. }
  12. }
  13. }
  14. return result;
  15. }

第72条 不要依赖于线程调度器

  * 不要让应用程序依赖线程调度器,也不要依赖 Thread.yield 或者线程优先级。这些设施仅仅对调度器作些暗示。

第73条 避免使用线程组

  * 最好把线程组当作一个不成功的实验,就当它们根本不存在一样。

  * 考虑使用线程池。

本文地址:https://www.cnblogs.com/laishenghao/p/9740851.html

《Effective Java》 学习笔记 —— 并发的更多相关文章

  1. Effective Java 学习笔记之第七条——避免使用终结(finalizer)方法

    避免使用终结方法(finalizer) 终结方法(finalizer)通常是不可预测的,也是很危险的,一般情况下是不必要的. 不要把finalizer当成C++中析构函数的对应物.java中,当对象不 ...

  2. Effective Java 阅读笔记——并发

    66:同步访问共享的可变数据 synchronized:1互斥,阻止线程看到的对象处于不一致的状态:2保证线程在进入同步区时能看到变量的被各个线程的所有修改 Java中,除了long或者double, ...

  3. Effective Java学习笔记

    创建和销毁对象 第一条:考虑用静态工厂方法替代构造器 For example: public static Boolean valueOf(boolean b){ return b ? Boolean ...

  4. Effective Java 学习笔记之所有对象都通用的方法

    一.覆盖equals时请遵守通用约定 1.满足下列任何一个条件时,不需要覆盖equals方法 a.类的每个实例本质上都是唯一的.此时就是Object中equals方法所表达的含义. b.不关心类是否提 ...

  5. Effective Java 学习笔记之创建和销毁对象

    一.考虑用静态工厂方法代替构造器 1.此处的静态工厂方法是指返回指为类的对象的静态方法,而不是设计模式中的静态工厂方法. 2.静态工厂方法的优势有: a.使用不同的方法名称可显著地表明两个静态工厂方法 ...

  6. Effective Java 学习笔记----第7章 通用程序设计

    第7章 通用程序设计 第29条 将局部变量的作用域最小化     使一个局部变量的作用域最小化,最有力的技术室在第一次使用它的地方声明.   第30条 了解和使用库      效率提高.如果你不知道库 ...

  7. effective java学习笔记之不可实例化的类

    在没有显式声明一个类的构造方法时,编译器会生成默认的无参构造方法,在设计工具类时,我们通常将方法设置成静态方法,以类名.方法名的形式调用,此时这个类就没有必要创建实例,我们知道抽象类不可以被实例化,但 ...

  8. Effective Java学习笔记--创建和销毁对象

    创建和销毁对象 一.静态工厂方法代替构造器 静态工厂方法的优缺点 优点: 1.可以自定义名称(可以将功能表述的更加清晰) 2.不必每次调用都创建新的对象(同一对象重复使用) 3.返回的类型可以是原返回 ...

  9. 《Java学习笔记(第8版)》学习指导

    <Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...

  10. java学习笔记14--多线程编程基础1

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note14.html,转载请注明源地址. 多线程编程基础 多进程 一个独立程序的每一次运行称为 ...

随机推荐

  1. SQL Server 如何设置数据库的默认初始大小和自动增长大小

    我们在SQL Server中新建数据库的时候,可以选择数据库文件及日志文件的初始大小.自动增长大小和最大大小,如下图所示: 可以通过设置更改数据库初始大小.自动增长大小和最大大小: 但是其实在SQL ...

  2. 获取 MySQL 崩溃时的 core file

    对于一般进程,要让进程崩溃时能生成 core file 用于调试,只需要设置 rlimit 的 core file size > 0 即可.比如,用在 ulimit -c unlimited 时 ...

  3. centos7 安装ldap

    ldap首先我们要知道这个ldap的概念, LDAP是轻量目录访问协议(Lightweight Directory Access Protocol)的缩写 目录是一个为查询.浏览和搜索而优化的专业分布 ...

  4. mySQL 约束 (Constraints)

    约束用于限制加入表的数据的类型: 1.创建表时规定约束(通过 CREATE TABLE 语句) 2.表创建之后也可以(通过 ALTER TABLE 语句). 约束类型: NOT NULL(非空) UN ...

  5. win10桌面显示我的电脑设置

      首先,我们可以看到桌面上面没有我的电脑.   我们在桌面空白处点击右键,选择“个性化”.   然后选择“更改桌面图标”,如图示.   在如图示位置,将“计算机”勾选,然后点击“应用”--" ...

  6. 端口扫描--zmap

    ZMap被设计用来针对整个IPv4地址空间或其中的大部分实施综合扫描的工具.ZMap是研究者手中的利器,但在运行ZMap时,请注意,您很有 可能正在以每秒140万个包的速度扫描整个IPv4地址空间 . ...

  7. 阿里八八Alpha阶段Scrum(9/12)

    今日进度 叶文滔: 成功完成多级悬浮按钮,并添加与日程输入界面的连接.debug了一些对接产生的问题 黄梅玲: 合并单日项目至多日.获取json数据 王国超: 完成了初步的多日界面,pull至项目.进 ...

  8. 【2017下集美大学软工1412班_助教博客】个人作业2——APP案例分析

    作业要求 个人作业2:APP案例分析 评分结果 按从高到低排列 学号后三位 第二次作业 Total 008 APP案例分析 23 044 第2次作业 19.5 011 App案例分析--XBMC 19 ...

  9. oc 的 协变性与逆变性

    ?协变性与逆变性是类型关系在范畴论的定义.是类型的继承关系在高阶类型中的定义? __kindof只是在统一继承体系下方便了类型转化,提供了使用时语法上的便捷:但是对于类型转换是否正确不做判定: kin ...

  10. Netty入门(七)使用SSL/TLS加密Netty程序

    为了支持 SSL/TLS,Java 提供了 javax.net.ssl API 的类 SslContext 和 SslEngine 使它相对简单的实现解密和加密.Netty 利用该 API 实现了 C ...