- 第一部分
竞态条件 Race Condition:先检查后执行(Check Then Act),即通过一个可能失效的观测结果来决定下一步的动作;我的理解:检查和执行分为先后两步,在检查后到执行前如果状态发生变化即可能导致错误
数据竞争 Data Race:如果在访问共享的非final对象类型的域时没采用同步来进行协同,那么就会出现数据竞争
synchronized锁:内置锁,可重入;
重入的一种实现方式:为每个锁关联一个获取计数值和一个所有者线程,当计数值为0,则认为没有被任何线程持有,当一个线程重复获取锁时,计数值将递增;
public class Widget {
public synchronized void doSomething() {
...
}
}
public class LoggingWidget extends Widget {
public synchronized void doSomething() {
System.out.println(toString() + ": calling doSomething");
super.doSomething();
}
}
super不是指的父类,而是:一个用来引用继承而来的成员的引用。
那么super.doSomething()的含义是,通过super引用调用从父类继承而来的doSomething()方法,所以锁的还是当前的子类对象
第四章:
63页
javadoc中大多并未描述类是否线程安全,你是否怀疑过这个类是否安全的?SimpleDateFormat并不是线程安全的,jdk 1.4之前的javadoc 并未提及这一点;
如果某个类没有明确声明是线程安全的,那么就不要假设它是线程安全的,从而有效避免SimpleDateFormat的问题
有时候你不得不去猜测某个类是否线程安全,另一种方法:从实现者的角度去解释规范,而不是从使用的角度,例如servlet相关的HttpSession和ServletContext;
P69
普通的容器类(如HashMap,HashSet,ArrayList等),在遍历时可能会抛出ConcurrentModificationException;所以遍历的时候需要注意遍历时的线程安全,还需要注意[隐式Iterator]调用,如toString方法,可能会隐式调用容器的遍历
CopyOnWriteArrayList 每当新数据被写入则重新创建发布当前数组的副本用于读取使用,不会抛出异常ConcurrentModificationException,适合于读多写少的情况