volatile修饰的变量,可以保证各个线程看到的是同一个值,但并不能保证其线程安全性。例如多个线程,并发对volatile变量进行数字运算,线程安全无法保证。也就是说,volatile可以保证可见性,但不能保证安全性。两种情况适合用volatile:
1、运算结果不依赖变量的当前值,或者只有一个线程能够修改变量的值
2、变量不需要与其他状态变量参与不变约束
volatile还可以禁止指令重排序优化。
Thread.isAlive检测线程是否已经终止执行
Thread.interrupted检测是否有中断发生
StringBuilder StringBuffer
后者是线程安全的,前者不是。
Vector ArrayList LinkedList
Vector线程安全,使用数组实现;ArrayList不是线程安全的,使用数组实现;LinkedList不是线程安全的,使用双向链表实现。
Hashtable线程安全 HashMap不是线程安全
HashMap无序,不保存输入顺序 LinkedHashMap可以保证输入顺序 TreeMap按照业务排序
Future模式适合于异步执行一个耗时较长的任务
Master-Worker模式适合于较为复杂的多任务协作
线程dump中,有几个关于同步的信息:
- parking to wait for 等待锁, java.util.concurrent包的各类锁
- waiting to lock 等待内部锁(intrinsic locks),来自synchronized方法
- locked ownable synchronizers 自己拥有的锁对象
使用自旋锁后,线程被挂起的几率相对减少,线程执行的连贯性相对加强。因此,对于那些锁竞争不是很激烈、锁占用时间很短的并发线程,是有一定的积极意义,但对于锁竞争激烈、单线程锁占用时间长的并发程序,自旋锁在自旋等待后,往往依然无法获得对应的锁,不仅仅白白浪费了CPU时间,最终还是免不了执行被挂起的操作,反而浪费了系统资源。