第二章 多线程技能
1、方法中的局部变量不存在“非线程安全”问题。
2、关键字synchronized取得的锁都是对象锁,而不是把一段代码或方法当作锁。
3、A线程先持有object对象的锁,B线程可以以异步的方式调用object对象中非synchronized类型的方法,但如果B对象在这时调用object对象中synchronized类型的方法则需要等待,也就是同步。
4、关键字synchronized拥有锁重入的功能,也就是在使用synchronized时,当一个线程得到一个对象后,再次请求此对象时是可以再次得到该对象的锁的。所以,在一个synchronized方法/块的内部调用其他synchronized方法/块时,是永远可以得到锁的。
5、当存在父子类继承关系时,子类是完全可以通过“可重入锁”调用父类的同步方法的。但同步不具有继承性。
6、当一个线程执行的代码出现异常时,所持有的锁会自动释放。
7、与synchronized一样,synchronized(this)也是锁定当前对象的。当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对同一个object中的其他synchronized(this)同步代码块的访问将被阻塞,这说明synchronized使用的是一个对象监视器。
8、多个线程调用同一个对象中不同名称的synchronized同步方法或synchronized(this)同步代码块时,调用的效果就是按顺序执行,也就是同步的,阻塞的。
9、synchronized(非this)具有一定的优点:如果在一个类中有很多个synchronized方法,这里虽然能实现同步,但会受到阻塞,所以会影响运行效率;但如果使用synchronized(非this),则与对象中的同步方法是异步的,不与其他锁this争抢this锁,可以大大的提高运行效率。
10、synchronized关键字加到static静态方法上是给Class上锁,而加到非static方法上是给对象上锁,且Class锁对所有的对象实例起作用。
11、在JVM中具有String常量池缓存的功能,所以在绝大多数情况下,synchronized代码块都不使用String作为锁对象。
12、volatile不能保证线程安全,不支持原子性。
13、volatile的主要作用是使变量在多个线程间可见,即强制从公共内存中读取变量的值。
14、线程安全包含原子性和可见性两个方面,Java同步机制都是围绕这两个方面来确保线程安全的。
15、synchronized与volatile比较:
1)volatile是线程同步的轻量级实现,所以性能比synchronized好,但volatile只能修饰变量。
2)多线程访问volatile不会发生阻塞,而synchronized会发生阻塞。
3)volatile能保存数据的可见性,但不能保证原子性;而synchronized可以保证原子性,也可以间接保证可见性。
16、对于用volatile修饰的变量,JVM虚拟机只是保证从主内在加载到线程工作内存的值是最新的,不能保证原子性。
17、原子操作是不可分割的整体,没有其他线程能够中断或检查正在原子操作的变量,它可以在没有锁的情况下做到线程安全。