《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 模式:

 private static class FieldHolder {
static final FieldType field = computeFieldValue();
} static FieldType getType() {
return FieldHolder.field;
}

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

 // volatile 很重要,保证可见性
private volatile FieldType field; FieldType getField() {
FieldType result = field;
if (result == null) {
synchronized(this) {
result = field;
if (result = null) {
field = result = computeFieldValue();
}
}
}
return result;
}

第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 经典面试题及答案(选课表)

    SQL数据库面试题以及答案 Student(Sno,Sname,Sage,Ssex) 学生表       Sno:学号:Sname:学生姓名:Sage:学生年龄:Ssex:学生性别Course(Cno ...

  2. 使用AndroidStudio上传忽略文件至SVN Server的解决措施

    在同组项目进行共享时,容易把本地的配置文件比如*.iml等文件上传至共享服务器,这样会对队友造成巨大的麻烦,为了解决这个问题,可以使用下面方法解决,下面以上传到服务器的app.iml文件为例. 一.在 ...

  3. Go语言学习笔记(六)net & net/http

    加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959 net import "net" net包提供了可移植的网络I/O接口,包括TCP/IP.UD ...

  4. 【Alpha 冲刺】 12/12

    今日任务总结 人员 今日原定任务 完成情况 遇到问题 贡献值 胡武成 完成app端api编写 已完成 JAVA后端跨域访问没有处理(目前已解决),导致前端localhost请求失败而误以为自己操作失误 ...

  5. Python os.md

    os 便携式访问操作系统的特定功能.os模块提供了对特定平台模块(如posix, nt, mac)的封装, 函数提供的api在很多平台上都可以相同使用, 所以使用os模块会变得很方便. 但不是所有函数 ...

  6. 关于军训的模拟赛-R2

    终于我也参加了一场有R1 && R2的比赛呢. 点击此处查看R1 因为种种原因,老师认为上次的考试没有体现我们的真实水平,于是举办了毒瘤R2,其实也不是非常毒瘤,还是一贯的风格. T1 ...

  7. Oracle Database(rdbms) 12.2 安装组件

    1. 工具用法 su - oracle $ $(orabasehome)/perl/bin/perl $ORACLE_HOME/rdbms/admin/catcon.pl Usage: catcon ...

  8. weex+vue2.x 踩坑实录(不定期更新)

    执行 npm start 显示空白页面 这个是开始使用weex就出现的一个大坑,说实话对新手真的很不友好. 1.打开控制台显示:Cannot assign to read only property ...

  9. 数据同步canal客户端

    1.增量订阅.消费设计 get/ack/rollback协议介绍: ① Message getWithoutAck(int batchSize),允许指定batchSize,一次可以获取多条,每次返回 ...

  10. css实现气泡框效果

    前提:气泡框或者提示框是网页很常见的,实现它的方式有很多,我们以前最常用的就是切图片 然后通过 "定位" 方式 定位到相应的位置,但是用这种方式维护很麻烦,比如设计师想改成另外一种 ...