1、方法内部的私有变量是线程安全的,实例变量是线程不安全的。
2、A线程先持有object对象的lock锁,B线程可以以异步的方式调用object对象中的非synchronized类型的方法。
3、A线程先持有object对象的lock锁,B线程如果调用object对象中的synchronized类型的方法,则需要等待,也就是同步。
4、脏读:在多线程中,发生脏读的情况是在读取实例变量时,此值已经被其它线程修改过。
5、锁重入:在使用synchronized时,当一个线程得到一个对象锁后,再次请求此对象锁时可以再次得到该对象的锁。
这也证明,在一个synchronized方法/块的内部调用本类的其它synchronized方法/块时,是可以得到锁的。
当存在父子类继承关系时,子类可以通过“可重入锁”调用父类的同步方法
6、当一个线程执行的代码出现异常时,其所持有的锁会自动释放
7、同步不可以继承,父类的同步方法,子类重写之后也要加上synchronized才会有同步效果
8、同步代码块,同步代码块比同步方法拥有更小纬度的同步,所以拥有更高的执行效率
9、同步代码块和同步方法一样,都是锁定的当前对象
10、多个线程调用一个同步方法的顺序是随机的
11、静态同步方法持有的是Class锁。
12、在JVM中具有String常量池缓存的功能,如果使用字符串变量作为锁,当两个变量的值相同时,就会造成两个线程持有相同的锁,后面的线程无法执行。这就是String常量池带来的问题
13、只要对象不变,即使对象的属性发生改变,运行的结果还是同步。
14、volatile关键字的作用是使变量在多个线程中可见。
15、volatile和synchronized的比较
1、volatile是线程同步的轻量级实现,性能比synchronized好,volatile只能修饰变量,synchronized可以修饰方法和代码块。
2、多线程访问volatile不会发生阻塞,synchronized会阻塞
3、volatile能保证数据的可见性,但不能保证原子性。synchronized可以保证原子性,并可以间接保证可见性。
16、变量在内存中的工作过程如下图
17、可以使用原子类Atomic来保证i++等操作的原子性