1, 保证线程安全的三种方法: 2, 一开始就将类设计成线程安全的, 比在后期重新修复它,更容易. 3, 编写多线程程序, 首先保证它是正确的, 其次再考虑性能. 4, 无状态或只读对象永远是线程安全的. 5, 不要将一个共享变量裸露在多线程环境下(无同步或不可变性保护) 6, 多线程环境下的延迟加载需要同步的保护, 因为延迟加载会造成对象重复实例化 7, 对于volatile声明的数值类型变量进行运算, 往往是不安全的(volatile只能保证可见性,不能保证原子性). 8, 当一个线程请求获得它自己占有的锁时(同一把锁的嵌套使用), 我们称该锁为可重入锁. 9, 每个共享变量,都应该由一个唯一确定的锁保护. 10,虽然缩小同步块的范围, 可以提升系统性能. 11, 在没有同步的情况下, 编译器与处理器运行时的指令执行顺序可能完全出乎意料. 12, 当一个线程在没有同步的情况下读取变量, 它可能会得到一个过期值, 但是至少它可以看到那个 在开发并发应用程序时, 有时为了大幅度提高系统的吞吐量与性能, 会采用这种无保障的做法. 13, volatile变量,只能保证可见性, 无法保证原子性. 14, 某些耗时较长的网络操作或IO, 确保执行时, 不要占有锁. 15, 发布(publish)对象, 指的是使它能够被当前范围之外的代码所使用.(引用传递) 原则: 为防止逸出, 对象必须要被完全构造完后, 才可以被发布(最好的解决方式是采用同步) this关键字引用对象逸出 16, 必要时, 使用ThreadLocal变量确保线程封闭性(封闭线程往往是比较安全的, 但一定程度上会造成性能损耗) 17, 单一不可变对象往往是线程安全的(复杂不可变对象需要保证其内部成员变量也是不可变的) 18, 保证共享变量的发布是安全的 19, 设计线程安全的类, 应该包括的基本要素: 20, 将数据封装在对象内部, 并保证对数据的访问是原子的. 21, 线程限制性使构造线程安全的类变得更容易, 因为类的状态被限制后, 分析它的线程安全性时, 就不必检查完整的程序. 22, 编写并发程序, 需要更全的注释, 更完整的文档说明. 23, 在需要细分锁的分配时, 使用java监视器模式好于使用自身对象的监视器锁. Object target = new Object(); 针对java monitor pattern, 实际上ReentrantLock的实现更易于并发编程. 24, 设计并发程序时, 在保证伸缩性与性能折中的前提下, 优先考虑将共享变量委托给线程安全的类. 25, 使用普通同步容器(Vector, Hashtable)的迭代器, 需要外部锁来保证其原子性. 26, 在并发编程中, 需要容器支持的时候, 优先考虑使用jdk并发容器 27, ConcurrentHashMap, CopyOnWriteArrayList 28, 使用有界队列, 在队列充满或为空时, 阻塞所有的读与写操作. (实现生产-消费的良好方案) 29, 当一个方法, 能抛出InterruptedException, 则意味着, 这个方法是一个可阻塞的方法, 如果它被中断, 将提前结束阻塞状态. 如果阻塞方法抛出了中断异常, 我们需要做的是, 将其往上层抛, 除非当前已经是需要捕获异常的层次. |
Java并发变成实践
最新推荐文章于 2024-07-29 14:22:26 发布