Java多线程中的Synchronized和volatile

Synchronized关键字:

1、方法中的变量不存在非线程安全问题,都是线程安全的。

2、两个线程访问同一个对象中的同步方法时,一定是线程安全的。

3、关键字synchronized取得的锁都是对象锁,而不是把一段代码或方法(函数)当作锁,哪个线程先执行synchronized关键字的方法,哪个线程就持有该方法所属对象的锁Lock,那么其他线程只能呈等待状态,前提是多个线程访问的是同一个对象。但如果多个线程访问多个对象,则JVM会创建多个锁。

4、调用关键字synchronized声明的方法一定是排队运行的。另外需要牢记“共享”两个字,只有共享资源的读写访问才需要同步化,如果不是共享资源,那么根本没同步的必要。

5、两个线程A和B,虽然线程A先持有了Object对象的锁,但线程B完全可以异步调用非synchronized类型的方法。

6、A线程先持有Object对象的Lock锁,B线程可以以异步的方式调用object对象中的非synchronized类型的方法。

7、A线程先持有object对象的Lock锁,B线程如果在这时调用Object对象中的synchronized类型的方法则需等待,也就是同步。

8、多个线程调用同一个方法时,为了避免数据出现交叉的情况,使用synchronized关键字进行同步。

9、脏读:在读取实例变量时,此值已经被其他线程更改过了。

10、当A线程调用anyObject对象加入synchronized关键字的X方法时,A线程就获得了X方法锁,更准确的讲,是获得了对象的锁,所以其他线程必须等A线程执行完毕才可以调用X方法,但B线程可以随意调用其他的非synchronized同步方法。

11、当A线程调用anyObject对象加入synchronized关键字的X方法是,A线程就获得了X方法所在的对象锁,所以其他线程必须等A线程执行完毕才可以调用X方法,而B线程如果调用声明了synchronized关键字的非X方法时,必须等A线程将X方法执行完,也就是释放对象锁后调用。

12、脏读一定会出现在操作实例变量的情况下,这就是不同线程争抢实例变量的结果。

13、synchronized锁重入:关键字synchronized拥有锁重入的功能,也就是在使用synchronized时,当一个线程得到一个对象锁后,再次请求此对象锁时是可以再次得到该对象的锁的。这也证明在一个synchronized方法/块内部调用本类其他synchronized方法/块时,是永远可以得到锁的。

14、当存在父子关系时,子类是完全可以通过“可重入锁”调用父类的同步方法的。

15、出现异常,锁自动释放。

16、同步不具有继承性。

17、当两个并发线程访问同一个对象object的synchronized(this)同步代码块时,一段时间只能有一个线程被执行,另一个线程必须等待当前线程执行完这个代码以后才能执行改代码块。

18、当一个线程访问object的synchronized同步代码块时,另一个线程仍然可以访问object中的非synchronized(this)同步代码块。

19、当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对同一个object中所有其他synchronized(this)同步代码块的访问将被阻塞。这说明synchronized使用的“对象监视器”是一个。

20、和synchronized方法一样,synchronized(this)代码块也是锁当前对象的。

21、使用synchronized(非this对象X)格式同步代码时,对象监视器必须是同一个对象。否则,结果就是异步调用,会交叉运行。

22、synchronized加到static静态方法上,是给Class上锁,加到非static静态方法上,是给对象上锁。

23、同步synchronized(class)的作用实际上和synchronized static的作用类似。

24、JVM中具有Spring常量池缓存的功能

String a = "a";
String b = "a";
a == b 返回true

25、在将任何数据类型作为同步锁时,需要注意的是,是否有多个线程同时持有锁对象,如果同时持有相同的锁对象,则这些线程之间就是同步的。如果分别获得所对象,则这些线程之间就是异步的。

26、只有锁对象不变,即使对象的属性变化,那么线程之前还是同步的。

volatile关键字:

1、volatile可以使变量在多个线程间可见。

2、强制从公共堆栈中取得变量的值,而不是从线程私有数据栈中获取数据。

3、增加了实例变量在多个线程之间的可见性,但是不支持原子性。

4、使用场合是在多个线程中可以感知实例变量被更改了,并且可以获取最新的值使用,也就是用多线程获取共享变量时,可以获得最新值使用。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/cea3ce383bb5f840d6e65ee28ed04ecd.html