Synchronized关键字---总结自《Java多线程编程核心技术》

1、方法内部的变量为线程安全

“非线程安全”问题存在于“实例变量”中,如果是方法内部的私有变量,则不存在“非线程安全”问题。这是方法内部的变量是私有的特性造成的

 

2、实例变量是非线程安全的

如果多个线程共同访问一个对象中得实例变量,则有可能造成“非线程安全”问题。

 

3、多个对象多个锁

锁的概念是针对对象的,每一个对象都会有锁(lock)关键字synchronized取得的锁都是对象锁,而不是把一段方法或者代码当做锁,哪个线程先执行带synchronized关键字的方法,哪个线程就持有该方法所属对象的锁(lock),那么其他线程都必须处在等待状态。

多个线程访问多个对象,则JVM会创建多个锁。

 

4、synchronized方法与锁对象

调用关键字synchronized声明的方法一定是排队运行的,只有共享资源的读写访问才需要同步,如果不是共享资源,那么根本没有同步的必要,多个方法被synchronized关键字修饰,多个线程调用这些方法也必须排队执行。

A线程先持有object对象的lock锁,B线程可以以异步的方式调用object对象中得非synchronized类型的方法

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

 

5、synchronized 锁重入

关键字synchronized拥有锁重入功能,也就是在使用synchronized时,当一个线程得到一个对象锁后,再次请求改对象锁时是可以再次得到该对象的锁的,简而言之,synchronized 方法/代码块内部调用奔雷的其他的synchronized方法/代码块,是永远可以得到锁的。此设计的基础是避免死锁,即有synchronized方法MethodA,在MethodA中调用了synchronized方法MethodB,是可以直接获取该锁的。而且在继承关系中,子类完全可以通过“可重入锁”调用父类的同步方法

 

6、出现异常,锁自动释放

 

7、同步不具备继承性

父类有synchronized方法SuperMethod(),子类重写父类该方法,未申明为synchronized的方法,子类的该方法并不具有synchronized属性,因为同步不具备继承性

 

8、synchronized方法的弊端

当线程持有某对象的锁的情况下,该方法需要做耗时操作的时候,别的线程需要长期等待,造成效率地下的问题。此处可以引入synchronized的代码块,通常可将赋值操作用synchronized(this)同步该赋值代码块,而耗时操作中保持异步执行,这样子的做法即保证了代码的异步高效,同时能够确保赋值操作的同步性,不会造成脏读。

 

9、synchronized代码块之间的同步性

在使用synchronized(this)代码块的时候需要注意的是:当一个线程访问object的synchronized(this)同步代码块时,其他线程对同一个object中所有其他的synchron(this)同步代码快的方法将被阻塞。

 

10、synchronized(this)代码块是锁定当前对象的

和synchronized方法一样,synchronized(this)代码块也是锁定当前对象的,也就是说持有的锁为当前对象的锁,线程A在调用ObjectA的sychronized(this)代码块时,线程B是无法调用ObjectA的synchronized方法的

 

11、将任意对象作为对象监视器

synchronized(非this对象)格式的作用只有一个种:synchronized(非this对象)同步代码块。在多个线程持有”线程监视器”为同一个对象的前提下,同一时间只有一个线程可以执行synchronized(非this对象)同步代码块中得代码,当持有”对象监视器”为同一个对象的前提下,同一时间只有一个线程可以执行synchronized(非this对象)同步代码块中得代码

synchronized(非this对象)的优点:如果一个类中有很多synchronized方法,这时虽然能够实现方法同步,但会收到阻塞,所以会影响运行效率,但如果使用synchronized(非this对象),此时该代码块与synchronized方法是异步的,不与其他锁this同步方法争抢this锁,可以大大提高运行效率。显然,synchronized中的对象必须是同一个对象,否则他们持有的锁就不是同一个锁了,所以就会造成异步。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页